001 /**
002  * Copyright (C) 2013 - Francesc Auli-Llinas
003  *
004  * This program is distributed under the BOI License.
005  * This program is distributed in the hope that it will be useful, but without any
006  * warranty; without even the implied warranty of merchantability or fitness for a particular purpose.
007  * You should have received a copy of the BOI License along with this program. If not,
008  * see <http://www.deic.uab.cat/~francesc/software/license/>.
009  */
010 package coders;
011 
012 import streams.ByteStream;
013 
014 
015 /**
016  * This class implements an arithmetic coder. The underlying coding scheme is based on the
017  * arithmetic coder MQ defined in the JPEG2000 standard (see the <code>ArithmeticCoderMQ</code> class
018  * for more details). This class can perform both the operations of the encoder and the decoder.<br>
019  *
020  * Usage: once the object is created, the functions to code/decode symbols are used to code the
021  * message. Instead of destroying the object and creating another one to encode a new message, it
022  * is more computationally efficient to reuse the same object. When encoding, the same object can be
023  * reused by calling the functions <code>terminate</code>, get the stream wherever is needed,
024  <code>changeStream</code><code>restartEncoding</code> and <code>reset</code> in this order.
025  * To reuse the decoder, the functions <code>changeStream</code><code>restartDecoding</code>, and
026  <code>reset</code> have to be called in this order.<br>
027  *
028  * Multithreading support: the object must be created and manipulated by a single thread. There
029  * can be many objects of this class running simultaneously as long as a single thread manipulates
030  * each object.<br>
031  *
032  @author Francesc Auli-Llinas
033  @version 1.0
034  */
035 public final class ArithmeticCoder{
036 
037   /**
038    * ByteStream employed by the coder to write/read the output/input bytes.
039    <p>
040    * The stream may contain zero bytes.
041    */
042   private ByteStream stream;
043 
044   /**
045    * Interval range.
046    <p>
047    * From right to left: 8 register bits, 3 spacer bits, 8 partial code bits, and 1 carry bit.
048    */
049   private int A;
050 
051   /**
052    * Lower down interval.
053    <p>
054    * From right to left: 8 register bits, 3 spacer bits, 8 partial code bits, and 1 carry bit.
055    */
056   private int C;
057 
058   /**
059    * Number of bits to transfer.
060    <p>
061    * It is set to 8 except when carry situations occur, in which is set to 7.
062    */
063   private int t;
064 
065   /**
066    * Byte to flush out/read.
067    <p>
068    * Flushed byte to the stream.
069    */
070   private int Tr;
071 
072   /**
073    * Current byte read/write.
074    <p>
075    * Current position in the stream.
076    */
077   private int L;
078 
079   /**
080    * Number of contexts.
081    <p>
082    * Set when the class is instantiated.
083    */
084   private int numContexts = -1;
085 
086   /**
087    * Current state of the context.
088    <p>
089    * Must in the range [0, STATE_TRANSITIONS_MPS.length - 1]
090    */
091   private int[] contextState = null;
092 
093   /**
094    * Most probable symbol of the Context.
095    <p>
096    * Either 0 or 1.
097    */
098   private int[] contextMPS = null;
099 
100   /**
101    * Transition to the next state when coding the most probable symbol.
102    <p>
103    * Each index must in the range [0, STATE_TRANSITIONS_MPS.length - 1]
104    */
105   private static final int[] STATE_TRANSITIONS_MPS = {123453878910,
106     1112132915161718192021222324252627282930,
107     3132333435363738394041424344454546};
108 
109   /**
110    * Transition to the next state when coding the least probable symbol.
111    <p>
112    * Each index must in the range [0, STATE_TRANSITIONS_MPS.length - 1]
113    */
114   private static final int[] STATE_TRANSITIONS_LPS = {16912293361414,
115     1417182021141415161718191920212223242526,
116     272829303132333435363738394041424346};
117 
118   /**
119    * Most probable symbol change.
120    <p>
121    * 1 indicates a change of the MPS.
122    */
123   private static final int[] STATE_CHANGE = {1000001000000,
124     01000000000000000000000000,
125     00000000};
126 
127   /**
128    * Probability of the context.
129    <p>
130    * The real probability can be computed as the coded probability expressed in this array 0xXXXX / (2^16 * \alpha), with \alpha = 0.708.
131    */
132   private static final int[] STATE_PROB = {0x56010x34010x18010x0AC10x0521,
133     0x02210x56010x54010x48010x38010x30010x24010x1C010x16010x5601,
134     0x54010x51010x48010x38010x34010x30010x28010x24010x22010x1C01,
135     0x18010x16010x14010x12010x11010x0AC10x09C10x08A10x05210x0441,
136     0x02A10x02210x01410x01110x00850x00490x00250x0015,  0x00090x0005,
137     0x00010x5601};
138 
139   /**
140    * Bit masks (employed when coding integers).
141    <p>
142    * The position in the array indicates the bit for which the mask is computed.
143    */
144   protected static final int[] BIT_MASKS = {1<< 1<< 2<< 3<< 4<< 5,
145     << 6<< 7<< 8<< 9<< 10<< 11<< 12<< 13<< 14<< 15,
146     << 16<< 17<< 18<< 19<< 20<< 21<< 22<< 23<< 24,
147     << 25<< 26<< 27<< 28<< 29<< 30};
148 
149 
150   /**
151    * Initializes internal registers. Before using the coder, a stream has to be set
152    * through <code>changeStream</code>.
153    */
154   public ArithmeticCoder(){
155     reset();
156     restartEncoding();
157   }
158 
159   /**
160    * Initializes internal registers and creates the number of contexts specified. Before
161    * using the coder, a stream has to be set through <code>changeStream</code>.
162    *
163    @param numContexts number of contexts available for this object
164    */
165   public ArithmeticCoder(int numContexts){
166     this.numContexts = numContexts;
167     contextState = new int[numContexts];
168     contextMPS = new int[numContexts];
169     reset();
170     restartEncoding();
171   }
172 
173   /**
174    * Encodes a bit using a context so that the probabilities are adaptively adjusted
175    * depending on the incoming symbols.
176    *
177    @param bit input
178    @param context context of the symbol
179    */
180   public void encodeBitContext(boolean bit, int context){
181     int x = bit ? 0;
182     int s = contextMPS[context];
183     int p = STATE_PROB[contextState[context]];
184 
185     A -= p;
186     if(x == s){ //Codes the most probable symbol
187       if(A >= (<< 15)){
188         C += p;
189       }else{
190         if(A < p){
191           A = p;
192         }else{
193           C += p;
194         }
195         contextState[context= STATE_TRANSITIONS_MPS[contextState[context]];
196         while(A < (<< 15)){
197           A <<= 1;
198           C <<= 1;
199           t--;
200           if(t == 0){
201             transferByte();
202           }
203         }
204       }
205     }else//Codes the least probable symbol
206       if(A < p){
207         C += p;
208       }else{
209         A = p;
210       }
211       if(STATE_CHANGE[contextState[context]] == 1){
212         contextMPS[context= contextMPS[context== 10//Switches MPS/LPS if necessary
213       }
214       contextState[context= STATE_TRANSITIONS_LPS[contextState[context]];
215       while(A < (<< 15)){
216         A <<= 1;
217         C <<= 1;
218         t--;
219         if(t == 0){
220           transferByte();
221         }
222       }
223     }
224   }
225 
226   /**
227    * Decodes a bit using a context so that the probabilities are adaptively adjusted
228    * depending on the outcoming symbols.
229    *
230    @param context context of the symbols
231    @return output bit
232    @throws Exception when some problem manipulating the stream occurs
233    */
234   public boolean decodeBitContext(int contextthrows Exception{
235     int p = STATE_PROB[contextState[context]];
236     int s = contextMPS[context];
237     int x = s;
238 
239     A -= p;
240     if((C & 0x00FFFF00>= (p << 8)){
241       C = ((C & ~0xFFFFFF00((C & 0x00FFFF00(p << 8)));
242       if(A < (<< 15)){
243         if(A < p){
244           x = - s;
245           if(STATE_CHANGE[contextState[context]] == 1){
246             contextMPS[context= contextMPS[context== 10//Switches MPS/LPS if necessary
247           }
248           contextState[context= STATE_TRANSITIONS_LPS[contextState[context]];
249         }else{
250           contextState[context= STATE_TRANSITIONS_MPS[contextState[context]];
251         }
252         while(A < (<< 15)){
253           if(t == 0){
254             fillLSB();
255           }
256           A <<= 1;
257           C <<= 1;
258           t--;
259         }
260       }
261     }else{
262       if(A < p){
263         contextState[context= STATE_TRANSITIONS_MPS[contextState[context]];
264       }else{
265         x = - s;
266         if(STATE_CHANGE[contextState[context]] == 1){
267           contextMPS[context= contextMPS[context== 10//Switches MPS/LPS if necessary
268         }
269         contextState[context= STATE_TRANSITIONS_LPS[contextState[context]];
270       }
271       A = p;
272       while(A < (<< 15)){
273         if(t == 0){
274           fillLSB();
275         }
276         A <<= 1;
277         C <<= 1;
278         t--;
279       }
280     }
281     return(x == 1);
282   }
283 
284   /**
285    * Encodes a bit using a specified probability.
286    *
287    @param bit input
288    @param prob0 through this parameter, the probability of the symbol to be 0 can be set.
289    * Let the real probability of the symbol to be 0 be denoted as P. Then, if P >= 0.5, prob0 is
290    * computed as prob0 = ((1f - P) * ((4f / 3f) * (float) 0x8000)), otherwise
291    * prob0 = - (P * ((4f / 3f) * (float) 0x8000)). Make sure that P = [0.0001f ,0.9999f].
292    * This operation is not carried out in the function to alleviate computational costs. See
293    * the function {@link #prob0ToMQ} and {@link #MQToProb0}.
294    */
295   public void encodeBitProb(boolean bit, int prob0){
296     int x = bit ? 0;
297     int p;
298     int s = 0;
299     if(prob0 >= 0){
300       p = prob0;
301     }else{
302       p = -prob0;
303       s = 1;
304     }
305 
306     A -= p;
307     if(x == s){ //Codes the most probable symbol
308       if(A >= (<< 15)){
309         C += p;
310       }else{
311         if(A < p){
312           A = p;
313         }else{
314           C += p;
315         }
316         while(A < (<< 15)){
317           A <<= 1;
318           C <<= 1;
319           t--;
320           if(t == 0){
321             transferByte();
322           }
323         }
324       }
325     }else//Codes the least probable symbol
326       if(A < p){
327         C += p;
328       }else{
329         A = p;
330       }
331       while(A < (<< 15)){
332         A <<= 1;
333         C <<= 1;
334         t--;
335         if(t == 0){
336           transferByte();
337         }
338       }
339     }
340   }
341 
342   /**
343    * Decodes a bit using a specified probability.
344    *
345    @param prob0 through this parameter, the probability of the symbol to be 0 can be
346    * set. Let the real probability of the symbol to be 0 be denoted as P. Then, if
347    * P >= 0.5, prob0 is computed as prob0 = ((1f - P) * ((4f / 3f) * (float) 0x8000)),
348    * otherwise prob0 = - (P * ((4f / 3f) * (float) 0x8000)). Make sure that P = [0.0001f ,0.9999f].
349    * This operation is not carried out in the function to alleviate computational costs. See the
350    * function {@link #prob0ToMQ} and {@link #MQToProb0}.
351    *
352    @return output bit
353    @throws Exception when some problem manipulating the stream occurs
354    */
355   public boolean decodeBitProb(int prob0throws Exception{
356     int p;
357     int s = 0;
358     if(prob0 >= 0){
359       p = prob0;
360     }else{
361       p = -prob0;
362       s = 1;
363     }
364     int x = s;
365 
366     A -= p;
367     if((C & 0x00FFFF00>= (p << 8)){
368       C = ((C & ~0xFFFFFF00((C & 0x00FFFF00(p << 8)));
369       if(A < (<< 15)){
370         if(A < p){
371           x = - s;
372         }
373         while(A < (<< 15)){
374           if(t == 0){
375             fillLSB();
376           }
377           A <<= 1;
378           C <<= 1;
379           t--;
380         }
381       }
382     }else{
383       if(A >= p){
384         x = - s;
385       }
386       A = p;
387       while(A < (<< 15)){
388         if(t == 0){
389           fillLSB();
390         }
391         A <<= 1;
392         C <<= 1;
393         t--;
394       }
395     }
396     return(x == 1);
397   }
398 
399   /**
400    * Transforms the probability of the symbol 0 (or false) in the range [0:1] into
401    * the integer required in the MQ coder to represent that probability.
402    *
403    @param prob0 in the range [0:1]
404    @return integer that can be feed to the MQ coder
405    */
406   public static int prob0ToMQ(float prob0){
407     int prob0MQ;
408     if(prob0 >= 0.5f){
409       prob0 = prob0 > 0.9999f 0.9999f: prob0;
410       prob0MQ = (int) ((1f - prob0((4f 3f(float0x8000));
411     }else{
412       prob0 = prob0 < 0.0001f 0.0001f: prob0;
413       prob0MQ = (int-(prob0 * ((4f 3f(float0x8000));
414     }
415     return(prob0MQ);
416   }
417 
418   /**
419    * Transforms the MQ integer to the probability of the symbol 0 (or false) in
420    * the range [0:1].
421    *
422    @param probMQ integer feed to the MQ coder
423    @return prob0 in the range [0:1]
424    */
425   public static float MQToProb0(int probMQ){
426     float prob0 = (3f (floatprobMQ(4f (float0x8000);
427     if(probMQ > 0){
428       prob0 = - prob0;
429     }else{
430       prob0 = -prob0;
431     }
432     return(prob0);
433   }
434 
435   /**
436    * Transfers a byte to the stream (for encoding purposes).
437    */
438   private void transferByte(){
439     if(Tr == 0xFF){ //Bit stuff
440       stream.putByte((byteTr);
441       L++;
442       Tr = (C >>> 20)//Puts C_msbs to Tr
443       C &= (~0xFFF00000)//Puts 0 to C_msbs
444       t = 7;
445     }else{
446       if(C >= 0x08000000){
447         //Propagates any carry bit from C into Tr
448         Tr += 0x01;
449         C &= (~0xF8000000)//Resets the carry bit
450       }
451       if(L >= 0){
452         stream.putByte((byteTr);
453       }
454       L++;
455       if(Tr == 0xFF){ //Bit stuff
456         //Although it may not be a bit carry
457         Tr = (C >>> 20)//Puts C_msbs to Tr
458         C &= (~0xFFF00000)//Puts 0 to C_msbs
459         t = 7;
460       }else{
461         Tr = (C >>> 19)//Puts C_partial to Tr
462         C &= (~0xFFF80000)//Puts 0 to C_partial
463         t = 8;
464       }
465     }
466   }
467 
468   /**
469    * Fills the C register with a byte from the stream or with 0xFF when the end of
470    * the stream is reached (for decoding purposes).
471    *
472    @throws Exception when some problem manipulating the stream occurs
473    */
474   private void fillLSB() throws Exception{
475     byte BL = 0;
476     t = 8;
477     if(L < stream.getLength()){
478       BL = stream.getByte(L);
479     }
480     //Reached the end of the stream
481     if((L == stream.getLength()) || ((Tr == 0xFF&& (BL > 0x8F))){
482       C += 0xFF;
483       if(L != stream.getLength()){
484         throw new Exception("Read marker 0xFF in the stream.");
485       }
486     }else{
487       if(Tr == 0xFF){
488         t = 7;
489       }
490       Tr = (0x000000FF (intBL);
491       L++;
492       C += (Tr << (- t));
493     }
494   }
495 
496   /**
497    * Changes the current stream. When encoding, before calling this function the stream
498    * should be terminated calling the <code>terminate</code> function, and after calling
499    * this function the functions <code>restartEncoding</code> and <code>reset</code> must
500    * be called. When decoding, after calling this function the functions <code>restartDecoding</code>
501    * and <code>reset</code> must be called.
502    *
503    @param stream the new ByteStream
504    */
505   public void changeStream(ByteStream stream){
506     if(stream == null){
507       stream = new ByteStream();
508     }
509     this.stream = stream;
510   }
511 
512   /**
513    * Resets the state of all contexts.
514    */
515   public void reset(){
516     for(int c = 0; c < numContexts; c++){
517       contextState[c0;
518       contextMPS[c0;
519     }
520   }
521 
522   /**
523    * Restarts the internal registers of the coder for encoding.
524    */
525   public void restartEncoding(){
526     A = 0x8000;
527     C = 0;
528     t = 12;
529     Tr = 0;
530     L = -1;
531   }
532 
533   /**
534    * Restarts the internal registers of the coder for decoding.
535    *
536    @throws Exception when some problem manipulating the stream occurs
537    */
538   public void restartDecoding() throws Exception{
539     Tr = 0;
540     L  = 0;
541     C  = 0;
542     fillLSB();
543     C <<= t;
544     fillLSB();
545     C <<= 7;
546     t -= 7;
547     A = 0x8000;
548   }
549 
550   /**
551    * Computes the number of bytes belonging to the currently encoded data needed to flush
552    * the internal registers (for encoding purposes). This function is useful to determine
553    * potential truncation points of the stream.
554    *
555    @return number of bytes
556    */
557   public int remainingBytes(){
558     if(27 - t <= 22){
559       return(4);
560     }else{
561       return(5);
562     }
563   }
564 
565   /**
566    * Terminates the current stream using the optimal termination (for encoding purposes).
567    *
568    @throws Exception when some problem manipulating the stream occurs
569    */
570   public void terminate() throws Exception{
571     terminateOptimal();
572   }
573 
574   /**
575    * Gets the number of bytes read or written to the stream associated to the coder.
576    *
577    @return the number of bytes
578    */
579   public int getReadBytes(){
580     return(L);
581   }
582 
583   /**
584    * Terminates the current stream using the easy termination (for encoding purposes).
585    */
586   public void terminateEasy(){
587     int nBits = 27 15 - t;
588     C <<= t;
589     while(nBits > 0){
590       transferByte();
591       nBits -= t;
592       C <<= t;
593     }
594     transferByte();
595     if(t == 7){
596       stream.removeByte();
597     }
598   }
599 
600   /**
601    * Terminates the current stream using the optimal termination (for encoding purposes).
602    *
603    @throws Exception when some problem manipulating the stream occurs
604    */
605   public void terminateOptimal() throws Exception{
606     int NZTr = Tr;
607     int NZt = t;
608     int NZC = C;
609     int NZA = A;
610     int NZL = L;
611 
612     int lengthEmptyTermination = (intstream.getLength();
613     terminateEasy();
614     int necessaryBytes = minFlush(NZTr, NZt, NZC, NZA, NZL, lengthEmptyTermination);
615     int lengthOptimalTermination = lengthEmptyTermination + necessaryBytes;
616 
617     if((lengthOptimalTermination >= 1&& ((stream.getByte(lengthOptimalTermination - 1== 0xFF))){
618       lengthOptimalTermination--;
619     }
620     boolean elimination;
621     do{
622       elimination = false;
623       if((lengthOptimalTermination >= 2&&
624       ((stream.getByte(lengthOptimalTermination - 2== 0xFF&&
625       (stream.getByte(lengthOptimalTermination - 1== 0x7F))){
626         lengthOptimalTermination -= 2;
627         elimination = true;
628       }
629     }while(elimination);
630     stream.removeBytes((intstream.getLength() - lengthOptimalTermination);
631   }
632 
633   /**
634    * Determines the minimum number of bytes needed to terminate the stream while assuring a
635    * complete recovering.
636    *
637    @param NZTr Tr register for the normalization
638    @param NZt t register for the normalization
639    @param NZC C register for the normalization
640    @param NZA A register for the normalization
641    @param NZL number of flushed bytes
642    @param lengthEmptyTermination length bytes used by the easy termination
643    @return the number of bytes that should be flushed to terminate the ByteStream optimally
644    *
645    @throws Exception when some problem manipulating the stream occurs
646    */
647   private int minFlush(int NZTr, int NZt, int NZC, int NZA, int NZL, int lengthEmptyTerminationthrows Exception{
648     long Cr = ((longNZTr << 27((longNZC << NZt);
649     long Ar = (longNZA << NZt;
650     long Rf = 0;
651     int s = 8;
652     int Sf = 35;
653 
654     int necessaryBytes = 0;
655     int maxNecessaryBytes = 5;
656     int cutZone = (intstream.getLength() - lengthEmptyTermination;
657     if(maxNecessaryBytes > cutZone){
658       maxNecessaryBytes = cutZone;
659     }
660     if((lengthEmptyTermination == 0&& (((Cr >> 320xFF== 0x00&& (NZL == -1)){
661       Cr <<= 8;
662       Ar <<= 8;
663     }
664     while((necessaryBytes < maxNecessaryBytes)
665       && ((Rf + ((long<< Sf< Cr)
666       || (Rf + ((long<< Sf>= Cr + Ar))){
667       necessaryBytes++;
668       if(necessaryBytes <= 4){
669         Sf -= s;
670         long b = stream.getByte(lengthEmptyTermination + necessaryBytes - 1);
671         if(b < 0){
672           b += 256;
673         }
674         Rf += b << Sf;
675         if(b == 0xFF){
676           s = 7;
677         }else{
678           s = 8;
679         }
680       }
681     }
682     return(necessaryBytes);
683   }
684 }
Java2html