/src/libjpeg-turbo.main/jdlossls.c
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | /*  | 
2  |  |  * jdlossls.c  | 
3  |  |  *  | 
4  |  |  * This file was part of the Independent JPEG Group's software:  | 
5  |  |  * Copyright (C) 1998, Thomas G. Lane.  | 
6  |  |  * Lossless JPEG Modifications:  | 
7  |  |  * Copyright (C) 1999, Ken Murchison.  | 
8  |  |  * libjpeg-turbo Modifications:  | 
9  |  |  * Copyright (C) 2022-2023, D. R. Commander.  | 
10  |  |  * For conditions of distribution and use, see the accompanying README.ijg  | 
11  |  |  * file.  | 
12  |  |  *  | 
13  |  |  * This file contains prediction, sample undifferencing, point transform, and  | 
14  |  |  * sample scaling routines for the lossless JPEG decompressor.  | 
15  |  |  */  | 
16  |  |  | 
17  |  | #define JPEG_INTERNALS  | 
18  |  | #include "jinclude.h"  | 
19  |  | #include "jpeglib.h"  | 
20  |  | #include "jlossls.h"  | 
21  |  |  | 
22  |  | #ifdef D_LOSSLESS_SUPPORTED  | 
23  |  |  | 
24  |  |  | 
25  |  | /**************** Sample undifferencing (reconstruction) *****************/  | 
26  |  |  | 
27  |  | /*  | 
28  |  |  * In order to avoid a performance penalty for checking which predictor is  | 
29  |  |  * being used and which row is being processed for each call of the  | 
30  |  |  * undifferencer, and to promote optimization, we have separate undifferencing  | 
31  |  |  * functions for each predictor selection value.  | 
32  |  |  *  | 
33  |  |  * We are able to avoid duplicating source code by implementing the predictors  | 
34  |  |  * and undifferencers as macros.  Each of the undifferencing functions is  | 
35  |  |  * simply a wrapper around an UNDIFFERENCE macro with the appropriate PREDICTOR  | 
36  |  |  * macro passed as an argument.  | 
37  |  |  */  | 
38  |  |  | 
39  |  | /* Predictor for the first column of the first row: 2^(P-Pt-1) */  | 
40  |  | #define INITIAL_PREDICTORx  (1 << (cinfo->data_precision - cinfo->Al - 1))  | 
41  |  |  | 
42  |  | /* Predictor for the first column of the remaining rows: Rb */  | 
43  |  | #define INITIAL_PREDICTOR2  prev_row[0]  | 
44  |  |  | 
45  |  |  | 
46  |  | /*  | 
47  |  |  * 1-Dimensional undifferencer routine.  | 
48  |  |  *  | 
49  |  |  * This macro implements the 1-D horizontal predictor (1).  INITIAL_PREDICTOR  | 
50  |  |  * is used as the special case predictor for the first column, which must be  | 
51  |  |  * either INITIAL_PREDICTOR2 or INITIAL_PREDICTORx.  The remaining samples  | 
52  |  |  * use PREDICTOR1.  | 
53  |  |  *  | 
54  |  |  * The reconstructed sample is supposed to be calculated modulo 2^16, so we  | 
55  |  |  * logically AND the result with 0xFFFF.  | 
56  |  |  */  | 
57  |  |  | 
58  |  | #define UNDIFFERENCE_1D(INITIAL_PREDICTOR) \  | 
59  | 87.7M  |   int Ra; \  | 
60  | 87.7M  |   \  | 
61  | 87.7M  |   Ra = (*diff_buf++ + INITIAL_PREDICTOR) & 0xFFFF; \  | 
62  | 87.7M  |   *undiff_buf++ = Ra; \  | 
63  | 87.7M  |   \  | 
64  | 597M  |   while (--width) { \ | 
65  | 510M  |     Ra = (*diff_buf++ + PREDICTOR1) & 0xFFFF; \  | 
66  | 510M  |     *undiff_buf++ = Ra; \  | 
67  | 510M  |   }  | 
68  |  |  | 
69  |  |  | 
70  |  | /*  | 
71  |  |  * 2-Dimensional undifferencer routine.  | 
72  |  |  *  | 
73  |  |  * This macro implements the 2-D horizontal predictors (#2-7).  PREDICTOR2 is  | 
74  |  |  * used as the special case predictor for the first column.  The remaining  | 
75  |  |  * samples use PREDICTOR, which is a function of Ra, Rb, and Rc.  | 
76  |  |  *  | 
77  |  |  * Because prev_row and output_buf may point to the same storage area (in an  | 
78  |  |  * interleaved image with Vi=1, for example), we must take care to buffer Rb/Rc  | 
79  |  |  * before writing the current reconstructed sample value into output_buf.  | 
80  |  |  *  | 
81  |  |  * The reconstructed sample is supposed to be calculated modulo 2^16, so we  | 
82  |  |  * logically AND the result with 0xFFFF.  | 
83  |  |  */  | 
84  |  |  | 
85  |  | #define UNDIFFERENCE_2D(PREDICTOR) \  | 
86  | 18.1M  |   int Ra, Rb, Rc; \  | 
87  | 18.1M  |   \  | 
88  | 18.1M  |   Rb = *prev_row++; \  | 
89  | 18.1M  |   Ra = (*diff_buf++ + PREDICTOR2) & 0xFFFF; \  | 
90  | 18.1M  |   *undiff_buf++ = Ra; \  | 
91  | 18.1M  |   \  | 
92  | 234M  |   while (--width) { \ | 
93  | 216M  |     Rc = Rb; \  | 
94  | 216M  |     Rb = *prev_row++; \  | 
95  | 216M  |     Ra = (*diff_buf++ + PREDICTOR) & 0xFFFF; \  | 
96  | 216M  |     *undiff_buf++ = Ra; \  | 
97  | 216M  |   }  | 
98  |  |  | 
99  |  |  | 
100  |  | /*  | 
101  |  |  * Undifferencers for the second and subsequent rows in a scan or restart  | 
102  |  |  * interval.  The first sample in the row is undifferenced using the vertical  | 
103  |  |  * predictor (2).  The rest of the samples are undifferenced using the  | 
104  |  |  * predictor specified in the scan header.  | 
105  |  |  */  | 
106  |  |  | 
107  |  | METHODDEF(void)  | 
108  |  | jpeg_undifference1(j_decompress_ptr cinfo, int comp_index,  | 
109  |  |                    JDIFFROW diff_buf, JDIFFROW prev_row,  | 
110  |  |                    JDIFFROW undiff_buf, JDIMENSION width)  | 
111  | 985k  | { | 
112  | 985k  |   UNDIFFERENCE_1D(INITIAL_PREDICTOR2);  | 
113  | 985k  | }  | 
114  |  |  | 
115  |  | METHODDEF(void)  | 
116  |  | jpeg_undifference2(j_decompress_ptr cinfo, int comp_index,  | 
117  |  |                    JDIFFROW diff_buf, JDIFFROW prev_row,  | 
118  |  |                    JDIFFROW undiff_buf, JDIMENSION width)  | 
119  | 843k  | { | 
120  | 843k  |   UNDIFFERENCE_2D(PREDICTOR2);  | 
121  | 843k  |   (void)(Rc);  | 
122  | 843k  | }  | 
123  |  |  | 
124  |  | METHODDEF(void)  | 
125  |  | jpeg_undifference3(j_decompress_ptr cinfo, int comp_index,  | 
126  |  |                    JDIFFROW diff_buf, JDIFFROW prev_row,  | 
127  |  |                    JDIFFROW undiff_buf, JDIMENSION width)  | 
128  | 2.04M  | { | 
129  | 2.04M  |   UNDIFFERENCE_2D(PREDICTOR3);  | 
130  | 2.04M  | }  | 
131  |  |  | 
132  |  | METHODDEF(void)  | 
133  |  | jpeg_undifference4(j_decompress_ptr cinfo, int comp_index,  | 
134  |  |                    JDIFFROW diff_buf, JDIFFROW prev_row,  | 
135  |  |                    JDIFFROW undiff_buf, JDIMENSION width)  | 
136  | 5.55M  | { | 
137  | 5.55M  |   UNDIFFERENCE_2D(PREDICTOR4);  | 
138  | 5.55M  | }  | 
139  |  |  | 
140  |  | METHODDEF(void)  | 
141  |  | jpeg_undifference5(j_decompress_ptr cinfo, int comp_index,  | 
142  |  |                    JDIFFROW diff_buf, JDIFFROW prev_row,  | 
143  |  |                    JDIFFROW undiff_buf, JDIMENSION width)  | 
144  | 3.25M  | { | 
145  | 3.25M  |   UNDIFFERENCE_2D(PREDICTOR5);  | 
146  | 3.25M  | }  | 
147  |  |  | 
148  |  | METHODDEF(void)  | 
149  |  | jpeg_undifference6(j_decompress_ptr cinfo, int comp_index,  | 
150  |  |                    JDIFFROW diff_buf, JDIFFROW prev_row,  | 
151  |  |                    JDIFFROW undiff_buf, JDIMENSION width)  | 
152  | 3.19M  | { | 
153  | 3.19M  |   UNDIFFERENCE_2D(PREDICTOR6);  | 
154  | 3.19M  | }  | 
155  |  |  | 
156  |  | METHODDEF(void)  | 
157  |  | jpeg_undifference7(j_decompress_ptr cinfo, int comp_index,  | 
158  |  |                    JDIFFROW diff_buf, JDIFFROW prev_row,  | 
159  |  |                    JDIFFROW undiff_buf, JDIMENSION width)  | 
160  | 3.21M  | { | 
161  | 3.21M  |   UNDIFFERENCE_2D(PREDICTOR7);  | 
162  | 3.21M  |   (void)(Rc);  | 
163  | 3.21M  | }  | 
164  |  |  | 
165  |  |  | 
166  |  | /*  | 
167  |  |  * Undifferencer for the first row in a scan or restart interval.  The first  | 
168  |  |  * sample in the row is undifferenced using the special predictor constant  | 
169  |  |  * x=2^(P-Pt-1).  The rest of the samples are undifferenced using the  | 
170  |  |  * 1-D horizontal predictor (1).  | 
171  |  |  */  | 
172  |  |  | 
173  |  | METHODDEF(void)  | 
174  |  | jpeg_undifference_first_row(j_decompress_ptr cinfo, int comp_index,  | 
175  |  |                             JDIFFROW diff_buf, JDIFFROW prev_row,  | 
176  |  |                             JDIFFROW undiff_buf, JDIMENSION width)  | 
177  | 86.7M  | { | 
178  | 86.7M  |   lossless_decomp_ptr losslessd = (lossless_decomp_ptr)cinfo->idct;  | 
179  |  |  | 
180  | 86.7M  |   UNDIFFERENCE_1D(INITIAL_PREDICTORx);  | 
181  |  |  | 
182  |  |   /*  | 
183  |  |    * Now that we have undifferenced the first row, we want to use the  | 
184  |  |    * undifferencer that corresponds to the predictor specified in the  | 
185  |  |    * scan header.  | 
186  |  |    */  | 
187  | 86.7M  |   switch (cinfo->Ss) { | 
188  | 4.89M  |   case 1:  | 
189  | 4.89M  |     losslessd->predict_undifference[comp_index] = jpeg_undifference1;  | 
190  | 4.89M  |     break;  | 
191  | 8.22M  |   case 2:  | 
192  | 8.22M  |     losslessd->predict_undifference[comp_index] = jpeg_undifference2;  | 
193  | 8.22M  |     break;  | 
194  | 16.7M  |   case 3:  | 
195  | 16.7M  |     losslessd->predict_undifference[comp_index] = jpeg_undifference3;  | 
196  | 16.7M  |     break;  | 
197  | 16.6M  |   case 4:  | 
198  | 16.6M  |     losslessd->predict_undifference[comp_index] = jpeg_undifference4;  | 
199  | 16.6M  |     break;  | 
200  | 13.0M  |   case 5:  | 
201  | 13.0M  |     losslessd->predict_undifference[comp_index] = jpeg_undifference5;  | 
202  | 13.0M  |     break;  | 
203  | 18.3M  |   case 6:  | 
204  | 18.3M  |     losslessd->predict_undifference[comp_index] = jpeg_undifference6;  | 
205  | 18.3M  |     break;  | 
206  | 9.01M  |   case 7:  | 
207  | 9.01M  |     losslessd->predict_undifference[comp_index] = jpeg_undifference7;  | 
208  | 9.01M  |     break;  | 
209  | 86.7M  |   }  | 
210  | 86.7M  | }  | 
211  |  |  | 
212  |  |  | 
213  |  | /*********************** Sample upscaling by 2^Pt ************************/  | 
214  |  |  | 
215  |  | METHODDEF(void)  | 
216  |  | simple_upscale(j_decompress_ptr cinfo,  | 
217  |  |                JDIFFROW diff_buf, _JSAMPROW output_buf, JDIMENSION width)  | 
218  | 56.2M  | { | 
219  | 379M  |   do { | 
220  | 379M  | #if BITS_IN_JSAMPLE == 12  | 
221  |  |     /* 12-bit is the only data precision for which the range of the sample data  | 
222  |  |      * type exceeds the valid sample range.  Thus, we need to range-limit the  | 
223  |  |      * samples, because other algorithms may try to use them as array indices.  | 
224  |  |      */  | 
225  | 379M  |     *output_buf++ = (_JSAMPLE)((*diff_buf++ << cinfo->Al) & 0xFFF);  | 
226  |  | #else  | 
227  |  |     *output_buf++ = (_JSAMPLE)(*diff_buf++ << cinfo->Al);  | 
228  |  | #endif  | 
229  | 379M  |   } while (--width);  | 
230  | 56.2M  | }  | 
231  |  |  | 
232  |  | METHODDEF(void)  | 
233  |  | noscale(j_decompress_ptr cinfo,  | 
234  |  |         JDIFFROW diff_buf, _JSAMPROW output_buf, JDIMENSION width)  | 
235  | 49.6M  | { | 
236  | 453M  |   do { | 
237  | 453M  | #if BITS_IN_JSAMPLE == 12  | 
238  | 453M  |     *output_buf++ = (_JSAMPLE)((*diff_buf++) & 0xFFF);  | 
239  |  | #else  | 
240  |  |     *output_buf++ = (_JSAMPLE)(*diff_buf++);  | 
241  |  | #endif  | 
242  | 453M  |   } while (--width);  | 
243  | 49.6M  | }  | 
244  |  |  | 
245  |  |  | 
246  |  | /*  | 
247  |  |  * Initialize for an input processing pass.  | 
248  |  |  */  | 
249  |  |  | 
250  |  | METHODDEF(void)  | 
251  |  | start_pass_lossless(j_decompress_ptr cinfo)  | 
252  | 75.7M  | { | 
253  | 75.7M  |   lossless_decomp_ptr losslessd = (lossless_decomp_ptr)cinfo->idct;  | 
254  | 75.7M  |   int ci;  | 
255  |  |  | 
256  |  |   /* Check that the scan parameters Ss, Se, Ah, Al are OK for lossless JPEG.  | 
257  |  |    *  | 
258  |  |    * Ss is the predictor selection value (psv).  Legal values for sequential  | 
259  |  |    * lossless JPEG are: 1 <= psv <= 7.  | 
260  |  |    *  | 
261  |  |    * Se and Ah are not used and should be zero.  | 
262  |  |    *  | 
263  |  |    * Al specifies the point transform (Pt).  | 
264  |  |    * Legal values are: 0 <= Pt <= (data precision - 1).  | 
265  |  |    */  | 
266  | 75.7M  |   if (cinfo->Ss < 1 || cinfo->Ss > 7 ||  | 
267  | 75.7M  |       cinfo->Se != 0 || cinfo->Ah != 0 ||  | 
268  | 75.7M  |       cinfo->Al < 0 || cinfo->Al >= cinfo->data_precision)  | 
269  | 154  |     ERREXIT4(cinfo, JERR_BAD_PROGRESSION,  | 
270  | 75.7M  |              cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);  | 
271  |  |  | 
272  |  |   /* Set undifference functions to first row function */  | 
273  | 303M  |   for (ci = 0; ci < cinfo->num_components; ci++)  | 
274  | 227M  |     losslessd->predict_undifference[ci] = jpeg_undifference_first_row;  | 
275  |  |  | 
276  |  |   /* Set scaler function based on Pt */  | 
277  | 75.7M  |   if (cinfo->Al)  | 
278  | 42.2M  |     losslessd->scaler_scale = simple_upscale;  | 
279  | 33.5M  |   else  | 
280  | 33.5M  |     losslessd->scaler_scale = noscale;  | 
281  | 75.7M  | }  | 
282  |  |  | 
283  |  |  | 
284  |  | /*  | 
285  |  |  * Initialize the lossless decompressor.  | 
286  |  |  */  | 
287  |  |  | 
288  |  | GLOBAL(void)  | 
289  |  | _jinit_lossless_decompressor(j_decompress_ptr cinfo)  | 
290  | 2.53k  | { | 
291  | 2.53k  |   lossless_decomp_ptr losslessd;  | 
292  |  |  | 
293  |  |   /* Create subobject in permanent pool */  | 
294  | 2.53k  |   losslessd = (lossless_decomp_ptr)  | 
295  | 2.53k  |     (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT,  | 
296  | 2.53k  |                                 sizeof(jpeg_lossless_decompressor));  | 
297  | 2.53k  |   cinfo->idct = (struct jpeg_inverse_dct *)losslessd;  | 
298  | 2.53k  |   losslessd->pub.start_pass = start_pass_lossless;  | 
299  | 2.53k  | } j12init_lossless_decompressor Line  | Count  | Source  |  290  | 826  | { |  291  | 826  |   lossless_decomp_ptr losslessd;  |  292  |  |  |  293  |  |   /* Create subobject in permanent pool */  |  294  | 826  |   losslessd = (lossless_decomp_ptr)  |  295  | 826  |     (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT,  |  296  | 826  |                                 sizeof(jpeg_lossless_decompressor));  |  297  | 826  |   cinfo->idct = (struct jpeg_inverse_dct *)losslessd;  |  298  | 826  |   losslessd->pub.start_pass = start_pass_lossless;  |  299  | 826  | }  |  
 j16init_lossless_decompressor Line  | Count  | Source  |  290  | 902  | { |  291  | 902  |   lossless_decomp_ptr losslessd;  |  292  |  |  |  293  |  |   /* Create subobject in permanent pool */  |  294  | 902  |   losslessd = (lossless_decomp_ptr)  |  295  | 902  |     (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT,  |  296  | 902  |                                 sizeof(jpeg_lossless_decompressor));  |  297  | 902  |   cinfo->idct = (struct jpeg_inverse_dct *)losslessd;  |  298  | 902  |   losslessd->pub.start_pass = start_pass_lossless;  |  299  | 902  | }  |  
 jinit_lossless_decompressor Line  | Count  | Source  |  290  | 807  | { |  291  | 807  |   lossless_decomp_ptr losslessd;  |  292  |  |  |  293  |  |   /* Create subobject in permanent pool */  |  294  | 807  |   losslessd = (lossless_decomp_ptr)  |  295  | 807  |     (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT,  |  296  | 807  |                                 sizeof(jpeg_lossless_decompressor));  |  297  | 807  |   cinfo->idct = (struct jpeg_inverse_dct *)losslessd;  |  298  | 807  |   losslessd->pub.start_pass = start_pass_lossless;  |  299  | 807  | }  |  
  | 
300  |  |  | 
301  |  | #endif /* D_LOSSLESS_SUPPORTED */  |