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