jdcol565.c (11909B)
1 /* 2 * jdcol565.c 3 * 4 * This file was part of the Independent JPEG Group's software: 5 * Copyright (C) 1991-1997, Thomas G. Lane. 6 * Modifications: 7 * Copyright (C) 2013, Linaro Limited. 8 * Copyright (C) 2014-2015, 2022, D. R. Commander. 9 * For conditions of distribution and use, see the accompanying README.ijg 10 * file. 11 * 12 * This file contains output colorspace conversion routines. 13 */ 14 15 /* This file is included by jdcolor.c */ 16 17 18 INLINE 19 LOCAL(void) 20 ycc_rgb565_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 21 JDIMENSION input_row, _JSAMPARRAY output_buf, 22 int num_rows) 23 { 24 #if BITS_IN_JSAMPLE != 16 25 my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert; 26 register int y, cb, cr; 27 register _JSAMPROW outptr; 28 register _JSAMPROW inptr0, inptr1, inptr2; 29 register JDIMENSION col; 30 JDIMENSION num_cols = cinfo->output_width; 31 /* copy these pointers into registers if possible */ 32 register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit; 33 register int *Crrtab = cconvert->Cr_r_tab; 34 register int *Cbbtab = cconvert->Cb_b_tab; 35 register JLONG *Crgtab = cconvert->Cr_g_tab; 36 register JLONG *Cbgtab = cconvert->Cb_g_tab; 37 SHIFT_TEMPS 38 39 while (--num_rows >= 0) { 40 JLONG rgb; 41 unsigned int r, g, b; 42 inptr0 = input_buf[0][input_row]; 43 inptr1 = input_buf[1][input_row]; 44 inptr2 = input_buf[2][input_row]; 45 input_row++; 46 outptr = *output_buf++; 47 48 if (PACK_NEED_ALIGNMENT(outptr)) { 49 y = *inptr0++; 50 cb = *inptr1++; 51 cr = *inptr2++; 52 r = range_limit[y + Crrtab[cr]]; 53 g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], 54 SCALEBITS))]; 55 b = range_limit[y + Cbbtab[cb]]; 56 rgb = PACK_SHORT_565(r, g, b); 57 *(INT16 *)outptr = (INT16)rgb; 58 outptr += 2; 59 num_cols--; 60 } 61 for (col = 0; col < (num_cols >> 1); col++) { 62 y = *inptr0++; 63 cb = *inptr1++; 64 cr = *inptr2++; 65 r = range_limit[y + Crrtab[cr]]; 66 g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], 67 SCALEBITS))]; 68 b = range_limit[y + Cbbtab[cb]]; 69 rgb = PACK_SHORT_565(r, g, b); 70 71 y = *inptr0++; 72 cb = *inptr1++; 73 cr = *inptr2++; 74 r = range_limit[y + Crrtab[cr]]; 75 g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], 76 SCALEBITS))]; 77 b = range_limit[y + Cbbtab[cb]]; 78 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b)); 79 80 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb); 81 outptr += 4; 82 } 83 if (num_cols & 1) { 84 y = *inptr0; 85 cb = *inptr1; 86 cr = *inptr2; 87 r = range_limit[y + Crrtab[cr]]; 88 g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], 89 SCALEBITS))]; 90 b = range_limit[y + Cbbtab[cb]]; 91 rgb = PACK_SHORT_565(r, g, b); 92 *(INT16 *)outptr = (INT16)rgb; 93 } 94 } 95 #else 96 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 97 #endif 98 } 99 100 101 INLINE 102 LOCAL(void) 103 ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 104 JDIMENSION input_row, _JSAMPARRAY output_buf, 105 int num_rows) 106 { 107 #if BITS_IN_JSAMPLE != 16 108 my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert; 109 register int y, cb, cr; 110 register _JSAMPROW outptr; 111 register _JSAMPROW inptr0, inptr1, inptr2; 112 register JDIMENSION col; 113 JDIMENSION num_cols = cinfo->output_width; 114 /* copy these pointers into registers if possible */ 115 register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit; 116 register int *Crrtab = cconvert->Cr_r_tab; 117 register int *Cbbtab = cconvert->Cb_b_tab; 118 register JLONG *Crgtab = cconvert->Cr_g_tab; 119 register JLONG *Cbgtab = cconvert->Cb_g_tab; 120 JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK]; 121 SHIFT_TEMPS 122 123 while (--num_rows >= 0) { 124 JLONG rgb; 125 unsigned int r, g, b; 126 127 inptr0 = input_buf[0][input_row]; 128 inptr1 = input_buf[1][input_row]; 129 inptr2 = input_buf[2][input_row]; 130 input_row++; 131 outptr = *output_buf++; 132 if (PACK_NEED_ALIGNMENT(outptr)) { 133 y = *inptr0++; 134 cb = *inptr1++; 135 cr = *inptr2++; 136 r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)]; 137 g = range_limit[DITHER_565_G(y + 138 ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], 139 SCALEBITS)), d0)]; 140 b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)]; 141 rgb = PACK_SHORT_565(r, g, b); 142 *(INT16 *)outptr = (INT16)rgb; 143 outptr += 2; 144 num_cols--; 145 } 146 for (col = 0; col < (num_cols >> 1); col++) { 147 y = *inptr0++; 148 cb = *inptr1++; 149 cr = *inptr2++; 150 r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)]; 151 g = range_limit[DITHER_565_G(y + 152 ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], 153 SCALEBITS)), d0)]; 154 b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)]; 155 d0 = DITHER_ROTATE(d0); 156 rgb = PACK_SHORT_565(r, g, b); 157 158 y = *inptr0++; 159 cb = *inptr1++; 160 cr = *inptr2++; 161 r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)]; 162 g = range_limit[DITHER_565_G(y + 163 ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], 164 SCALEBITS)), d0)]; 165 b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)]; 166 d0 = DITHER_ROTATE(d0); 167 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b)); 168 169 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb); 170 outptr += 4; 171 } 172 if (num_cols & 1) { 173 y = *inptr0; 174 cb = *inptr1; 175 cr = *inptr2; 176 r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)]; 177 g = range_limit[DITHER_565_G(y + 178 ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], 179 SCALEBITS)), d0)]; 180 b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)]; 181 rgb = PACK_SHORT_565(r, g, b); 182 *(INT16 *)outptr = (INT16)rgb; 183 } 184 } 185 #else 186 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 187 #endif 188 } 189 190 191 INLINE 192 LOCAL(void) 193 rgb_rgb565_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 194 JDIMENSION input_row, _JSAMPARRAY output_buf, 195 int num_rows) 196 { 197 register _JSAMPROW outptr; 198 register _JSAMPROW inptr0, inptr1, inptr2; 199 register JDIMENSION col; 200 JDIMENSION num_cols = cinfo->output_width; 201 SHIFT_TEMPS 202 203 while (--num_rows >= 0) { 204 JLONG rgb; 205 unsigned int r, g, b; 206 207 inptr0 = input_buf[0][input_row]; 208 inptr1 = input_buf[1][input_row]; 209 inptr2 = input_buf[2][input_row]; 210 input_row++; 211 outptr = *output_buf++; 212 if (PACK_NEED_ALIGNMENT(outptr)) { 213 r = *inptr0++; 214 g = *inptr1++; 215 b = *inptr2++; 216 rgb = PACK_SHORT_565(r, g, b); 217 *(INT16 *)outptr = (INT16)rgb; 218 outptr += 2; 219 num_cols--; 220 } 221 for (col = 0; col < (num_cols >> 1); col++) { 222 r = *inptr0++; 223 g = *inptr1++; 224 b = *inptr2++; 225 rgb = PACK_SHORT_565(r, g, b); 226 227 r = *inptr0++; 228 g = *inptr1++; 229 b = *inptr2++; 230 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b)); 231 232 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb); 233 outptr += 4; 234 } 235 if (num_cols & 1) { 236 r = *inptr0; 237 g = *inptr1; 238 b = *inptr2; 239 rgb = PACK_SHORT_565(r, g, b); 240 *(INT16 *)outptr = (INT16)rgb; 241 } 242 } 243 } 244 245 246 INLINE 247 LOCAL(void) 248 rgb_rgb565D_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 249 JDIMENSION input_row, _JSAMPARRAY output_buf, 250 int num_rows) 251 { 252 register _JSAMPROW outptr; 253 register _JSAMPROW inptr0, inptr1, inptr2; 254 register JDIMENSION col; 255 register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit; 256 JDIMENSION num_cols = cinfo->output_width; 257 JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK]; 258 SHIFT_TEMPS 259 260 while (--num_rows >= 0) { 261 JLONG rgb; 262 unsigned int r, g, b; 263 264 inptr0 = input_buf[0][input_row]; 265 inptr1 = input_buf[1][input_row]; 266 inptr2 = input_buf[2][input_row]; 267 input_row++; 268 outptr = *output_buf++; 269 if (PACK_NEED_ALIGNMENT(outptr)) { 270 r = range_limit[DITHER_565_R(*inptr0++, d0)]; 271 g = range_limit[DITHER_565_G(*inptr1++, d0)]; 272 b = range_limit[DITHER_565_B(*inptr2++, d0)]; 273 rgb = PACK_SHORT_565(r, g, b); 274 *(INT16 *)outptr = (INT16)rgb; 275 outptr += 2; 276 num_cols--; 277 } 278 for (col = 0; col < (num_cols >> 1); col++) { 279 r = range_limit[DITHER_565_R(*inptr0++, d0)]; 280 g = range_limit[DITHER_565_G(*inptr1++, d0)]; 281 b = range_limit[DITHER_565_B(*inptr2++, d0)]; 282 d0 = DITHER_ROTATE(d0); 283 rgb = PACK_SHORT_565(r, g, b); 284 285 r = range_limit[DITHER_565_R(*inptr0++, d0)]; 286 g = range_limit[DITHER_565_G(*inptr1++, d0)]; 287 b = range_limit[DITHER_565_B(*inptr2++, d0)]; 288 d0 = DITHER_ROTATE(d0); 289 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b)); 290 291 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb); 292 outptr += 4; 293 } 294 if (num_cols & 1) { 295 r = range_limit[DITHER_565_R(*inptr0, d0)]; 296 g = range_limit[DITHER_565_G(*inptr1, d0)]; 297 b = range_limit[DITHER_565_B(*inptr2, d0)]; 298 rgb = PACK_SHORT_565(r, g, b); 299 *(INT16 *)outptr = (INT16)rgb; 300 } 301 } 302 } 303 304 305 INLINE 306 LOCAL(void) 307 gray_rgb565_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 308 JDIMENSION input_row, _JSAMPARRAY output_buf, 309 int num_rows) 310 { 311 register _JSAMPROW inptr, outptr; 312 register JDIMENSION col; 313 JDIMENSION num_cols = cinfo->output_width; 314 315 while (--num_rows >= 0) { 316 JLONG rgb; 317 unsigned int g; 318 319 inptr = input_buf[0][input_row++]; 320 outptr = *output_buf++; 321 if (PACK_NEED_ALIGNMENT(outptr)) { 322 g = *inptr++; 323 rgb = PACK_SHORT_565(g, g, g); 324 *(INT16 *)outptr = (INT16)rgb; 325 outptr += 2; 326 num_cols--; 327 } 328 for (col = 0; col < (num_cols >> 1); col++) { 329 g = *inptr++; 330 rgb = PACK_SHORT_565(g, g, g); 331 g = *inptr++; 332 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(g, g, g)); 333 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb); 334 outptr += 4; 335 } 336 if (num_cols & 1) { 337 g = *inptr; 338 rgb = PACK_SHORT_565(g, g, g); 339 *(INT16 *)outptr = (INT16)rgb; 340 } 341 } 342 } 343 344 345 INLINE 346 LOCAL(void) 347 gray_rgb565D_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 348 JDIMENSION input_row, _JSAMPARRAY output_buf, 349 int num_rows) 350 { 351 register _JSAMPROW inptr, outptr; 352 register JDIMENSION col; 353 register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit; 354 JDIMENSION num_cols = cinfo->output_width; 355 JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK]; 356 357 while (--num_rows >= 0) { 358 JLONG rgb; 359 unsigned int g; 360 361 inptr = input_buf[0][input_row++]; 362 outptr = *output_buf++; 363 if (PACK_NEED_ALIGNMENT(outptr)) { 364 g = *inptr++; 365 g = range_limit[DITHER_565_R(g, d0)]; 366 rgb = PACK_SHORT_565(g, g, g); 367 *(INT16 *)outptr = (INT16)rgb; 368 outptr += 2; 369 num_cols--; 370 } 371 for (col = 0; col < (num_cols >> 1); col++) { 372 g = *inptr++; 373 g = range_limit[DITHER_565_R(g, d0)]; 374 rgb = PACK_SHORT_565(g, g, g); 375 d0 = DITHER_ROTATE(d0); 376 377 g = *inptr++; 378 g = range_limit[DITHER_565_R(g, d0)]; 379 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(g, g, g)); 380 d0 = DITHER_ROTATE(d0); 381 382 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb); 383 outptr += 4; 384 } 385 if (num_cols & 1) { 386 g = *inptr; 387 g = range_limit[DITHER_565_R(g, d0)]; 388 rgb = PACK_SHORT_565(g, g, g); 389 *(INT16 *)outptr = (INT16)rgb; 390 } 391 } 392 }