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