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 18INLINE 19LOCAL(void) 20ycc_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, 21 JDIMENSION input_row, JSAMPARRAY output_buf, 22 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 = *inptr0++; 49 cb = *inptr1++; 50 cr = *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 = *inptr0++; 62 cb = *inptr1++; 63 cr = *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 = *inptr0++; 71 cb = *inptr1++; 72 cr = *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 = *inptr0; 84 cb = *inptr1; 85 cr = *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 97INLINE 98LOCAL(void) 99ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, 100 JDIMENSION input_row, JSAMPARRAY output_buf, 101 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 = *inptr0++; 129 cb = *inptr1++; 130 cr = *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 = *inptr0++; 143 cb = *inptr1++; 144 cr = *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 = *inptr0++; 154 cb = *inptr1++; 155 cr = *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 = *inptr0; 169 cb = *inptr1; 170 cr = *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 183INLINE 184LOCAL(void) 185rgb_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, 186 JDIMENSION input_row, JSAMPARRAY output_buf, 187 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 = *inptr0++; 206 g = *inptr1++; 207 b = *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 = *inptr0++; 215 g = *inptr1++; 216 b = *inptr2++; 217 rgb = PACK_SHORT_565(r, g, b); 218 219 r = *inptr0++; 220 g = *inptr1++; 221 b = *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 = *inptr0; 229 g = *inptr1; 230 b = *inptr2; 231 rgb = PACK_SHORT_565(r, g, b); 232 *(INT16 *)outptr = (INT16)rgb; 233 } 234 } 235} 236 237 238INLINE 239LOCAL(void) 240rgb_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, 241 JDIMENSION input_row, JSAMPARRAY output_buf, 242 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(*inptr0++, d0)]; 263 g = range_limit[DITHER_565_G(*inptr1++, d0)]; 264 b = range_limit[DITHER_565_B(*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(*inptr0++, d0)]; 272 g = range_limit[DITHER_565_G(*inptr1++, d0)]; 273 b = range_limit[DITHER_565_B(*inptr2++, d0)]; 274 d0 = DITHER_ROTATE(d0); 275 rgb = PACK_SHORT_565(r, g, b); 276 277 r = range_limit[DITHER_565_R(*inptr0++, d0)]; 278 g = range_limit[DITHER_565_G(*inptr1++, d0)]; 279 b = range_limit[DITHER_565_B(*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(*inptr0, d0)]; 288 g = range_limit[DITHER_565_G(*inptr1, d0)]; 289 b = range_limit[DITHER_565_B(*inptr2, d0)]; 290 rgb = PACK_SHORT_565(r, g, b); 291 *(INT16 *)outptr = (INT16)rgb; 292 } 293 } 294} 295 296 297INLINE 298LOCAL(void) 299gray_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, 300 JDIMENSION input_row, JSAMPARRAY output_buf, 301 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 337INLINE 338LOCAL(void) 339gray_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, 340 JDIMENSION input_row, JSAMPARRAY output_buf, 341 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