]> Creatis software - gdcm.git/blob - src/gdcmjpegls/Encoder/lossless_e.c
ENH: avoid writing illegal images with a double dots.
[gdcm.git] / src / gdcmjpegls / Encoder / lossless_e.c
1 /* SPMG/JPEG-LS IMPLEMENTATION V.2.1
2    =====================================
3    These programs are Copyright (c) University of British Columbia. All rights reserved.
4    They may be freely redistributed in their entirety provided that this copyright
5    notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
6    COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
7    Each program is provided as is, without any express or implied warranty,
8    without even the warranty of fitness for a particular purpose.
9
10    =========================================================
11    THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
12    =========================================================
13
14    LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
15    -------------------------------------------------------------------------------
16    (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
17         HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
18    COMPLETENESS OF THE INFORMATION GIVEN HERE.  ANY USE MADE OF, OR
19    RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
20         BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
21    ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
22    OF THIS LICENSING AGREEMENT.
23         YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
24    FREE OF CHARGE OR FURTHER OBLIGATION.  YOU MAY NOT, DIRECTLY OR
25    INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
26    SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
27    TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
28         YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
29    OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
30    HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
31    SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
32         THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
33    THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
34    FINAL OR FULL IMPLEMENTATION OF THE STANDARD.  HP GIVES NO EXPRESS OR
35    IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
36    MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
37         HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
38    OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
39    -------------------------------------------------------------------------------
40 */
41
42 /* lossless_e.c --- the main pipeline which processes a scanline by doing
43  *                prediction, context computation, context quantization,
44  *                and statistics gathering.
45  *
46  * Initial code by Alex Jakulin,  Aug. 1995
47  *
48  * Modified and optimized: Gadiel Seroussi, October 1995
49  *
50  * Modified and added Restart marker and input tables by:
51  * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
52  */
53
54 #include <stdio.h>
55 #include <math.h>
56
57 #include "global.h"
58 #include "bitio.h"
59
60
61 /*byte getk[65][3000];*/
62 /*byte clipPx[510];*/
63
64 static int eor_limit;
65
66
67 /* Do Golomb statistics and ENCODING for LOSS-LESS images */
68 inline void lossless_regular_mode(int Q, int SIGN, int Px, pixel *xp)
69 {
70   int At, Nt, Bt, absErrval, Errval, MErrval,
71       Ix = *xp;  /* current pixel */
72   int  unary;
73   int temp;
74   byte k;
75
76   Nt = N[Q];
77     At = A[Q];
78   
79   
80   /* Prediction correction (A.4.2), compute prediction error (A.4.3)
81      , and error quantization (A.4.4) */
82   Px = Px + (SIGN) * C[Q];
83 /*Px = clipPx[Px+127];*/
84   clip(Px,alpha);
85   Errval = SIGN * (Ix - Px);
86
87
88   /* Modulo reduction of predication error (A.4.5) */
89   if (Errval < 0)
90     Errval += alpha;     /* Errval is now in [0.. alpha-1] */
91   
92
93   /* Estimate k - Golomb coding variable computation (A.5.1) */
94   {
95       register nst = Nt;
96     for(k=0; nst < At; nst<<=1, k++);
97   }
98 /*k=getk[Nt][At];*/
99
100
101   /* Do Rice mapping and compute magnitude of Errval */
102   Bt = B[Q];
103
104   /* Error Mapping (A.5.2) */
105   temp = ( k==0 && ((Bt<<1) <= -Nt) );
106   if (Errval >= ceil_half_alpha) {
107     Errval -= alpha;
108     absErrval = -Errval;
109     MErrval = (absErrval<<1) - 1 - temp;
110   } else {
111     absErrval = Errval;
112     MErrval = (Errval<<1) + temp;
113   }
114       
115
116   /* update bias stats (after correction of the difference) (A.6.1) */
117   B[Q] = (Bt += Errval);
118
119
120   /* update Golomb stats */
121   A[Q] += absErrval;
122
123
124   /* check for reset */
125   if (Nt == reset) {
126   /* reset for Golomb and bias cancelation at the same time */
127     N[Q] = (Nt >>= 1);
128     A[Q] >>= 1;
129     B[Q] = (Bt >>= 1);
130   }
131   N[Q] = (++Nt);
132
133
134   /* Do bias estimation for NEXT pixel */
135   /* Bias cancelation tries to put error in (-1,0] (A.6.2)*/  
136   if  ( Bt <= -Nt ) {
137
138       if (C[Q] > MIN_C)
139       --C[Q];
140
141       if ( (B[Q] += Nt) <= -Nt ) 
142       B[Q] = -Nt+1;
143
144   } else if ( Bt > 0 ) {
145       
146       if (C[Q] < MAX_C)
147       ++C[Q];
148     
149     if ( (B[Q] -= Nt) > 0 )
150       B[Q] = 0;
151   }
152
153   
154   /* Actually output the code: Mapped Error Encoding (Appendix G) */
155   unary = MErrval >> k;
156   if ( unary < limit ) {
157       put_zeros(unary);
158     putbits((1 << k) + (MErrval & ((1 << k) - 1)), k + 1);
159   }
160   else {
161       put_zeros(limit);
162       putbits((1<<qbpp) + MErrval - 1, qbpp+1);
163   }
164 }
165
166
167
168
169 /* Do end of run encoding for LOSSLESS images */
170 inline void lossless_end_of_run(pixel Ra, pixel Rb, pixel Ix, int RItype)
171 {
172   int Errval,
173     MErrval,
174     Q,
175     absErrval,
176     oldmap,
177     k,
178     At,
179     unary;
180   
181   register int Nt;
182
183   Q = EOR_0 + RItype;
184   Nt = N[Q];
185   At = A[Q];
186
187   Errval = Ix - Rb;
188   if (RItype)
189     At += Nt>>1;
190   else {
191     if ( Rb < Ra )
192       Errval = -Errval;
193   }
194
195
196   /* Estimate k */
197   for(k=0; Nt < At; Nt<<=1, k++);
198           
199   if (Errval < 0)
200     Errval += alpha;
201   if( Errval >= ceil_half_alpha )
202     Errval -= alpha;
203       
204   
205   oldmap = ( k==0 && Errval && (B[Q]<<1)<Nt );     
206   /*  Note: the Boolean variable 'oldmap' is not 
207     identical to the variable 'map' in the
208     JPEG-LS draft. We have
209     oldmap = (Errval<0) ? (1-map) : map;
210   */
211
212   /* Error mapping for run-interrupted sample (Figure A.22) */      
213   if( Errval < 0) {
214     MErrval = -(Errval<<1)-1-RItype+oldmap;
215     B[Q]++; 
216   }else
217     MErrval = (Errval<<1)-RItype-oldmap;
218   
219   absErrval = (MErrval+1-RItype)>>1;
220
221   /* Update variables for run-interruped sample (Figure A.23) */
222   A[Q] += absErrval;
223   if (N[Q] == reset) {
224     N[Q] >>= 1;
225     A[Q] >>= 1;
226     B[Q] >>= 1;
227   }
228
229   N[Q]++; /* for next pixel */
230
231   /* Do the actual Golomb encoding: */
232   eor_limit = limit - limit_reduce;
233   unary = MErrval >> k;
234   if ( unary < eor_limit ) {
235     put_zeros(unary);
236     putbits((1 << k) + (MErrval & ((1 << k) - 1)), k + 1);
237   }
238   else {
239     put_zeros(eor_limit);
240     putbits((1<<qbpp) + MErrval-1, qbpp+1);
241   }
242 }
243
244
245
246
247
248
249 /* For line and plane interleaved mode in LOSS-LESS mode */
250
251 void lossless_doscanline( pixel *psl,            /* previous scanline */
252         pixel *sl,             /* current scanline */
253         int no, int color)     /* number of values in it */
254
255 /*** watch it! actual pixels in the scan line are numbered 1 to no .
256      pixels with indices < 1 or > no are dummy "border" pixels  */
257 {
258   int i;
259   pixel Ra, Rb, Rc, Rd,   /* context pixels */
260         Ix,              /* current pixel */
261         Px;         /* predicted current pixel */
262
263   int SIGN;          /* sign of current context */
264   int cont;        /* context */
265
266   i = 1;    /* pixel indices in a scan line go from 1 to no */
267
268   /**********************************************/
269   /* Do for all pixels in the row in 8-bit mode */
270   /**********************************************/
271   if (bpp16==FALSE) {
272     
273     Rc = psl[0];
274     Rb = psl[1];
275     Ra = sl[0];
276
277     /*  For 8-bit Image */
278
279     do {
280       int RUNcnt;
281
282       Ix = sl[i];
283       Rd = psl[i + 1];
284
285       /* Context determination */
286
287       /* Quantize the gradient */
288       /* partial context number: if (b-e) is used then its 
289          contribution is added after determination of the run state.
290          Also, sign flipping, if any, occurs after run
291          state determination */
292
293
294       cont =  vLUT[0][Rd - Rb + LUTMAX8] +
295           vLUT[1][Rb - Rc + LUTMAX8] +
296           vLUT[2][Rc - Ra + LUTMAX8];
297
298       if ( cont == 0 )
299       {
300     /*************** RUN STATE ***************************/
301
302         RUNcnt = 0;
303
304         if (Ix == Ra) {
305           while ( 1 ) {
306
307             ++RUNcnt;
308
309             if (++i > no) {  
310               /* Run-lenght coding when reach end of line (A.7.1.2) */
311               process_run(RUNcnt, EOLINE, color);
312               return;   /* end of line */
313             }
314
315             Ix = sl[i];
316
317             if (Ix != Ra)  /* Run is broken */
318             {
319               Rd = psl[i + 1];
320               Rb = psl[i];
321               break;  /* out of while loop */
322             }
323             /* Run continues */
324           }
325         }
326
327         /* we only get here if the run is broken by
328            a non-matching symbol */
329
330         /* Run-lenght coding when end of line not reached (A.7.1.2) */
331         process_run(RUNcnt,NOEOLINE, color);
332
333
334         /* This is the END_OF_RUN state */
335         lossless_end_of_run(Ra, Rb, Ix, (Ra==Rb));
336
337       }           
338       else {
339
340     /*************** REGULAR CONTEXT *******************/
341
342         predict(Rb, Ra, Rc);
343
344         /* do symmetric context merging */
345         cont = classmap[cont];
346   
347         if (cont<0) {
348           SIGN=-1;
349           cont = -cont;
350         }
351         else
352           SIGN=+1;
353
354         /* output a rice code */
355         lossless_regular_mode(cont, SIGN, Px, &Ix);
356       }
357
358       /* context for next pixel: */
359       sl[i] = Ix;
360
361       Ra = Ix;
362       Rc = Rb;
363       Rb = Rd;
364     } while (++i <= no);  
365
366   }
367   else
368   {
369     /***********************************************/
370     /* Do for all pixels in the row in 16-bit mode */
371     /***********************************************/
372
373     Rc = ENDIAN16(psl[0]);
374     Rb = ENDIAN16(psl[1]);
375     Ra = ENDIAN16(sl[0]);
376
377     /*  For 16-bit Image */
378
379     do {
380       int RUNcnt;
381
382       Ix = ENDIAN16(sl[i]);
383       Rd = ENDIAN16(psl[i + 1]);
384
385       /* Context determination */
386
387       /* Quantize the gradient */
388       /* partial context number: if (b-e) is used then its 
389          contribution is added after determination of the run state.
390          Also, sign flipping, if any, occurs after run
391          state determination */
392
393     
394       {
395         register int diff;
396
397         /* Following segment assumes that T3 <= LUTMAX16 */
398         /* This condition should have been checked when the
399           lookup tables were built */
400         diff = Rd - Rb;
401         if (diff < 0)
402           cont = (diff > -LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 7*CREGIONS*CREGIONS;
403         else 
404           cont = (diff < LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 8*CREGIONS*CREGIONS;
405
406         diff = Rb - Rc;
407         if (diff < 0)
408           cont += (diff > -LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 7*CREGIONS;
409         else 
410           cont += (diff < LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 8*CREGIONS;
411
412         diff = Rc - Ra;
413         if (diff < 0)
414           cont += (diff > -LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 7;
415         else 
416           cont += (diff < LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 8;
417       }
418
419
420       if ( cont == 0 ) {      /* Run state? */
421
422     /*************** RUN STATE ***************************/
423
424         RUNcnt = 0;
425
426         if (Ix == Ra) {
427           while ( 1 ) {
428           
429             ++RUNcnt;
430
431             if (++i > no) {  
432               /* Run-lenght coding when reach end of line (A.7.1.2) */
433               process_run(RUNcnt, EOLINE, color);
434               return;   /* end of line */
435             }
436
437             Ix = ENDIAN16(sl[i]);
438
439             if (Ix != Ra)  /* Run is broken */
440             {
441               Rd = ENDIAN16(psl[i + 1]);
442               Rb = ENDIAN16(psl[i]);
443               break;  /* out of while loop */
444             }
445             /* Run continues */
446           }
447         }
448
449         /* we only get here if the run is broken by
450            a non-matching symbol */
451
452         /* Run-lenght coding when end of line not reached (A.7.1.2) */
453         process_run(RUNcnt,NOEOLINE, color);
454
455         /* This is the END_OF_RUN state */
456         lossless_end_of_run(Ra, Rb, Ix, (Ra==Rb));
457
458       }
459       else {
460
461     /*************** REGULAR CONTEXT *******************/
462
463         predict(Rb, Ra, Rc);
464
465         /* do symmetric context merging */
466         cont = classmap[cont];
467   
468         if (cont<0) {
469           SIGN=-1;
470           cont = -cont;
471         }
472         else
473           SIGN=+1;
474
475         /* output a rice code */
476         lossless_regular_mode(cont, SIGN, Px, &Ix);
477       }
478
479       /* context for next pixel: */
480       sl[i] = ENDIAN16(Ix);
481       Ra = Ix;
482       Rc = Rb;
483       Rb = Rd;
484     } while (++i <= no);
485   }
486 }
487
488
489
490
491
492
493 /* For pixel interleaved mode for LOSSLESS encoding */
494
495 void lossless_doscanline_pixel(  pixel *psl,            /* previous scanline */
496                 pixel *sl,             /* current scanline */
497                 int no)                /* number of values in it */
498
499 /*** watch it! actual pixels in the scan line are numbered 1 to no .
500      pixels with indices < 1 or > no are dummy "border" pixels  */
501 {
502   int i,n_c, enter_run=0, break_run, was_in_run=0, test_run;
503   int color;          /* Index to the component, 0..COMPONENTS-1 */
504   pixel c_aa[MAX_COMPONENTS],
505         c_bb[MAX_COMPONENTS],
506         c_cc[MAX_COMPONENTS],
507         c_dd[MAX_COMPONENTS],
508         c_xx[MAX_COMPONENTS],
509         Ra, Rb, Rc, Rd,            /* context pixels */
510         Ix,        /* current pixel */
511         Px;         /* predicted current pixel */
512   int SIGN;        /* sign of current context */
513   int cont,c_cont[MAX_COMPONENTS];        /* context */
514
515
516   if (bpp16==FALSE)
517   {
518   /**********************************************/
519   /* Do for all pixels in the row in 8-bit mode */
520   /**********************************************/
521
522     for (n_c=0; n_c<components; n_c++) {
523       c_cc[n_c] = ENDIAN8(psl[n_c]);
524       c_bb[n_c] = ENDIAN8(psl[components+n_c]);
525       c_aa[n_c] = ENDIAN8(sl[n_c]);
526     }
527
528     i = components;    /* pixel indices in a scan line go from COMPONENTS to no */
529     color = -1;
530     
531     do {
532       int RUNcnt;
533
534       if (!was_in_run) color = (color+1)%components;
535       else color = 0;
536
537       Ix = ENDIAN8(sl[i]);
538
539       for (n_c=0;n_c<components;n_c++)
540         c_xx[n_c]=ENDIAN8(sl[i+n_c]);
541
542       if (color == 0)
543         for (n_c=0;n_c<components;n_c++)
544         {
545           c_dd[n_c] = ENDIAN8(psl[i+components+n_c]);
546
547           /* Context determination */
548
549           /* Quantize the gradient */
550           /* partial context number: if (b-e) is used
551              then its contribution is added after
552              determination of the run state.
553              Also, sign flipping, if any, occurs after run
554              state determination */
555
556           c_cont[n_c] =  vLUT[0][c_dd[n_c] - c_bb[n_c] + LUTMAX8] +
557                   vLUT[1][c_bb[n_c] - c_cc[n_c] + LUTMAX8] +
558                   vLUT[2][c_cc[n_c] - c_aa[n_c] + LUTMAX8];
559         }
560
561       Ra=c_aa[color];
562       Rb=c_bb[color];
563       Rc=c_cc[color];
564       Rd=c_dd[color];
565       cont=c_cont[color];
566
567       enter_run = was_in_run = test_run = 0;
568
569       if (color == 0) {
570         test_run = 1;
571         for (n_c=0;n_c<components;n_c++)
572           if (c_cont[n_c]!=0) {
573             test_run=0;
574             break;
575           }
576       }
577
578       /* Run state? */
579       if ( test_run ) { 
580       /*************** RUN STATE ***************************/
581
582         enter_run = was_in_run = 1;
583         for (n_c=0;n_c<components;n_c++) 
584           if (ENDIAN8(sl[i+n_c]) != c_bb[n_c]) enter_run=0;
585         RUNcnt = 0;
586         if (enter_run)
587         {
588           while ( 1 ) {
589             ++RUNcnt;
590
591             if((i=i+components)>(no+components-1)){  
592               process_run(RUNcnt, EOLINE, 0);
593               return;   /* end of line */
594             }
595
596             for (n_c=0;n_c<components;n_c++) 
597               c_xx[n_c] = ENDIAN8(sl[i+n_c]);
598
599             break_run=0;
600
601             for (n_c=0;n_c<components;n_c++) 
602               if (c_xx[n_c] != c_aa[n_c]) break_run=1;
603
604             if (break_run)   /* Run is broken */
605             {
606               for(n_c=0;n_c<components;n_c++){
607                 c_dd[n_c] = ENDIAN8(psl[i+components+n_c]);
608                 c_bb[n_c] = ENDIAN8(psl[i+n_c]);
609               }
610               break;  /* out of while loop */
611             }
612             /* Run continues */
613           }
614         }
615
616         /* we only get here if the run is broken by
617           a non-matching symbol */
618
619         process_run(RUNcnt,NOEOLINE, 0);
620
621         /* This is the END_OF_RUN state */
622         for (n_c=0;n_c<components;n_c++)
623         {
624           /* The end of run is done for each component */
625           Ix = c_xx[n_c];
626           Ra = c_aa[n_c];
627           Rb = c_bb[n_c];
628
629           lossless_end_of_run(Ra, Rb, Ix, 0);
630
631         }   /* loop for components */
632
633       }        /* Run state block */
634       else {
635       
636       /*************** REGULAR CONTEXT *******************/
637
638         predict(Rb, Ra, Rc);
639         cont = classmap[cont];
640
641         if (cont<0) {
642           SIGN=-1;
643           cont=-cont;
644         } else
645           SIGN=1;
646
647         /* output a rice code */
648         lossless_regular_mode(cont, SIGN, Px, &Ix);
649       }
650
651       /* context for next pixel: */
652       if (!was_in_run) {
653         c_aa[color] = Ix;
654         c_cc[color] = Rb;
655         c_bb[color] = Rd;
656         i++;
657       }
658       else {
659         for(n_c=0;n_c<components;n_c++) {
660           c_aa[n_c] = c_xx[n_c];
661           c_cc[n_c] = c_bb[n_c];
662           c_bb[n_c] = c_dd[n_c];
663         }
664         i += components;
665       }
666
667     } while (i <= (no+components-1));
668
669   } else {
670
671   /**********************************************/
672   /* Do for all pixels in the row in 16-bit mode*/
673   /**********************************************/
674
675     for (n_c=0; n_c<components; n_c++) {
676       c_cc[n_c] = ENDIAN16(psl[n_c]);
677       c_bb[n_c] = ENDIAN16(psl[components+n_c]);
678       c_aa[n_c] = ENDIAN16(sl[n_c]);
679     }
680
681     i = components;    /* pixel indices in a scan line go from COMPONENTS to no */
682     color = -1;
683     
684     do {
685       int RUNcnt;
686
687       if (!was_in_run) color = (color+1)%components;
688       else color = 0;
689
690       Ix = ENDIAN16(sl[i]);
691
692       for (n_c=0;n_c<components;n_c++)
693         c_xx[n_c]=ENDIAN16(sl[i+n_c]);
694
695       if (color == 0)
696         for (n_c=0;n_c<components;n_c++)
697         {
698           c_dd[n_c] = ENDIAN16(psl[i+components+n_c]);
699
700           /* Context determination */
701
702           /* Quantize the gradient */
703           /* partial context number: if (b-e) is used
704              then its contribution is added after
705              determination of the run state.
706              Also, sign flipping, if any, occurs after run
707              state determination */
708
709           {
710           register int diff;
711
712           /* Following segment assumes that Sc <= LUTMAX16 */
713           /* This condition should have been checked when the
714             lookup tables were built */
715           diff = c_dd[n_c] - c_bb[n_c];
716           if (diff < 0)
717             c_cont[n_c] = (diff > -LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 7*CREGIONS*CREGIONS;
718           else 
719             c_cont[n_c] = (diff < LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 8*CREGIONS*CREGIONS;
720
721           diff = c_bb[n_c] - c_cc[n_c];
722           if (diff < 0)
723             c_cont[n_c] += (diff > -LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 7*CREGIONS;
724           else 
725             c_cont[n_c] += (diff < LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 8*CREGIONS;
726
727           diff = c_cc[n_c] - c_aa[n_c];
728           if (diff < 0)
729             c_cont[n_c] += (diff > -LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 7;
730           else 
731             c_cont[n_c] += (diff < LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 8;
732           }
733         }
734
735       Ra=c_aa[color];
736       Rb=c_bb[color];
737       Rc=c_cc[color];
738       Rd=c_dd[color];
739       cont=c_cont[color];
740
741       enter_run = was_in_run = test_run = 0;
742
743       if (color == 0) {
744         test_run = 1;
745         for (n_c=0;n_c<components;n_c++)
746           if (c_cont[n_c]!=0) {
747             test_run=0;
748             break;
749           }
750       }
751
752       /* Run state? */
753       if ( test_run ) { 
754       /*************** RUN STATE ***************************/
755
756         enter_run = was_in_run = 1;
757         for (n_c=0;n_c<components;n_c++) 
758           if (ENDIAN16(sl[i+n_c]) != c_bb[n_c]) enter_run=0;
759         RUNcnt = 0;
760         if (enter_run)
761         {
762           while ( 1 ) {
763             ++RUNcnt;
764
765             if((i=i+components)>(no+components-1)){  
766               process_run(RUNcnt, EOLINE, 0);
767               return;   /* end of line */
768             }
769
770             for (n_c=0;n_c<components;n_c++) 
771               c_xx[n_c] = ENDIAN16(sl[i+n_c]);
772
773             break_run=0;
774
775             for (n_c=0;n_c<components;n_c++) 
776               if (c_xx[n_c] != c_aa[n_c]) break_run=1;
777
778             if (break_run)   /* Run is broken */
779             {
780               for(n_c=0;n_c<components;n_c++){
781                 c_dd[n_c] = ENDIAN16(psl[i+components+n_c]);
782                 c_bb[n_c] = ENDIAN16(psl[i+n_c]);
783               }
784               break;  /* out of while loop */
785             }
786             /* Run continues */
787           }
788         }
789
790         /* we only get here if the run is broken by
791           a non-matching symbol */
792
793         process_run(RUNcnt,NOEOLINE, 0);
794
795         /* This is the END_OF_RUN state */
796         for (n_c=0;n_c<components;n_c++)
797         {
798           /* The end of run is done for each component */
799           Ix = c_xx[n_c];
800           Ra = c_aa[n_c];
801           Rb = c_bb[n_c];
802           
803           lossless_end_of_run(Ra, Rb, Ix, 0);
804
805         }   /* loop for components */
806
807       }        /* Run state block */
808       else {
809       
810       /*************** REGULAR CONTEXT *******************/
811
812         predict(Rb, Ra, Rc);
813         cont = classmap[cont];
814       
815         if (cont<0) {
816           SIGN=-1;
817           cont=-cont;
818         } else
819           SIGN=1;
820
821         /* output a rice code */
822         lossless_regular_mode(cont, SIGN, Px, &Ix);
823       }
824
825       /* context for next pixel: */
826       if (!was_in_run) {
827         c_aa[color] = Ix;
828         c_cc[color] = Rb;
829         c_bb[color] = Rd;
830         i++;
831       }
832       else {
833         for(n_c=0;n_c<components;n_c++) {
834           c_aa[n_c] = c_xx[n_c];
835           c_cc[n_c] = c_bb[n_c];
836           c_bb[n_c] = c_dd[n_c];
837         }
838         i += components;
839       }
840
841     } while (i <= (no+components-1));
842
843   } /* ends "if" for 8 or 16 bit */
844
845 }