jdlossls.c (8522B)
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, 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 int Ra; \ 60 \ 61 Ra = (*diff_buf++ + INITIAL_PREDICTOR) & 0xFFFF; \ 62 *undiff_buf++ = Ra; \ 63 \ 64 while (--width) { \ 65 Ra = (*diff_buf++ + PREDICTOR1) & 0xFFFF; \ 66 *undiff_buf++ = Ra; \ 67 } 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 int Ra, Rb, Rc; \ 87 \ 88 Rb = *prev_row++; \ 89 Ra = (*diff_buf++ + PREDICTOR2) & 0xFFFF; \ 90 *undiff_buf++ = Ra; \ 91 \ 92 while (--width) { \ 93 Rc = Rb; \ 94 Rb = *prev_row++; \ 95 Ra = (*diff_buf++ + PREDICTOR) & 0xFFFF; \ 96 *undiff_buf++ = Ra; \ 97 } 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 { 112 UNDIFFERENCE_1D(INITIAL_PREDICTOR2); 113 } 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 { 120 UNDIFFERENCE_2D(PREDICTOR2); 121 (void)(Rc); 122 } 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 { 129 UNDIFFERENCE_2D(PREDICTOR3); 130 } 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 { 137 UNDIFFERENCE_2D(PREDICTOR4); 138 } 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 { 145 UNDIFFERENCE_2D(PREDICTOR5); 146 } 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 { 153 UNDIFFERENCE_2D(PREDICTOR6); 154 } 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 { 161 UNDIFFERENCE_2D(PREDICTOR7); 162 (void)(Rc); 163 } 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 { 178 lossless_decomp_ptr losslessd = (lossless_decomp_ptr)cinfo->idct; 179 180 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 switch (cinfo->Ss) { 188 case 1: 189 losslessd->predict_undifference[comp_index] = jpeg_undifference1; 190 break; 191 case 2: 192 losslessd->predict_undifference[comp_index] = jpeg_undifference2; 193 break; 194 case 3: 195 losslessd->predict_undifference[comp_index] = jpeg_undifference3; 196 break; 197 case 4: 198 losslessd->predict_undifference[comp_index] = jpeg_undifference4; 199 break; 200 case 5: 201 losslessd->predict_undifference[comp_index] = jpeg_undifference5; 202 break; 203 case 6: 204 losslessd->predict_undifference[comp_index] = jpeg_undifference6; 205 break; 206 case 7: 207 losslessd->predict_undifference[comp_index] = jpeg_undifference7; 208 break; 209 } 210 } 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 { 219 do { 220 *output_buf++ = (_JSAMPLE)(*diff_buf++ << cinfo->Al); 221 } while (--width); 222 } 223 224 METHODDEF(void) 225 noscale(j_decompress_ptr cinfo, 226 JDIFFROW diff_buf, _JSAMPROW output_buf, JDIMENSION width) 227 { 228 do { 229 *output_buf++ = (_JSAMPLE)(*diff_buf++); 230 } while (--width); 231 } 232 233 234 /* 235 * Initialize for an input processing pass. 236 */ 237 238 METHODDEF(void) 239 start_pass_lossless(j_decompress_ptr cinfo) 240 { 241 lossless_decomp_ptr losslessd = (lossless_decomp_ptr)cinfo->idct; 242 int ci; 243 244 /* Check that the scan parameters Ss, Se, Ah, Al are OK for lossless JPEG. 245 * 246 * Ss is the predictor selection value (psv). Legal values for sequential 247 * lossless JPEG are: 1 <= psv <= 7. 248 * 249 * Se and Ah are not used and should be zero. 250 * 251 * Al specifies the point transform (Pt). 252 * Legal values are: 0 <= Pt <= (data precision - 1). 253 */ 254 if (cinfo->Ss < 1 || cinfo->Ss > 7 || 255 cinfo->Se != 0 || cinfo->Ah != 0 || 256 cinfo->Al < 0 || cinfo->Al >= cinfo->data_precision) 257 ERREXIT4(cinfo, JERR_BAD_PROGRESSION, 258 cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al); 259 260 /* Set undifference functions to first row function */ 261 for (ci = 0; ci < cinfo->num_components; ci++) 262 losslessd->predict_undifference[ci] = jpeg_undifference_first_row; 263 264 /* Set scaler function based on Pt */ 265 if (cinfo->Al) 266 losslessd->scaler_scale = simple_upscale; 267 else 268 losslessd->scaler_scale = noscale; 269 } 270 271 272 /* 273 * Initialize the lossless decompressor. 274 */ 275 276 GLOBAL(void) 277 _jinit_lossless_decompressor(j_decompress_ptr cinfo) 278 { 279 lossless_decomp_ptr losslessd; 280 281 /* Create subobject in permanent pool */ 282 losslessd = (lossless_decomp_ptr) 283 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT, 284 sizeof(jpeg_lossless_decompressor)); 285 cinfo->idct = (struct jpeg_inverse_dct *)losslessd; 286 losslessd->pub.start_pass = start_pass_lossless; 287 } 288 289 #endif /* D_LOSSLESS_SUPPORTED */