1 /* 2 * jdcolext.c 3 * 4 * This file was part of the Independent JPEG Group's software: 5 * Copyright (C) 1991-1997, Thomas G. Lane. 6 * libjpeg-turbo Modifications: 7 * Copyright (C) 2009, 2011, D. R. Commander. 8 * For conditions of distribution and use, see the accompanying README file. 9 * 10 * This file contains output colorspace conversion routines. 11 */ 12 13 14 /* This file is included by jdcolor.c */ 15 16 17 /* 18 * Convert some rows of samples to the output colorspace. 19 * 20 * Note that we change from noninterleaved, one-plane-per-component format 21 * to interleaved-pixel format. The output buffer is therefore three times 22 * as wide as the input buffer. 23 * A starting row offset is provided only for the input buffer. The caller 24 * can easily adjust the passed output_buf value to accommodate any row 25 * offset required on that side. 26 */ 27 28 INLINE 29 LOCAL(void) 30 ycc_rgb_convert_internal (j_decompress_ptr cinfo, 31 JSAMPIMAGE input_buf, JDIMENSION input_row, 32 JSAMPARRAY output_buf, int num_rows) 33 { 34 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; 35 register int y, cb, cr; 36 register JSAMPROW outptr; 37 register JSAMPROW inptr0, inptr1, inptr2; 38 register JDIMENSION col; 39 JDIMENSION num_cols = cinfo->output_width; 40 /* copy these pointers into registers if possible */ 41 register JSAMPLE * range_limit = cinfo->sample_range_limit; 42 register int * Crrtab = cconvert->Cr_r_tab; 43 register int * Cbbtab = cconvert->Cb_b_tab; 44 register INT32 * Crgtab = cconvert->Cr_g_tab; 45 register INT32 * Cbgtab = cconvert->Cb_g_tab; 46 SHIFT_TEMPS 47 48 while (--num_rows >= 0) { 49 inptr0 = input_buf[0][input_row]; 50 inptr1 = input_buf[1][input_row]; 51 inptr2 = input_buf[2][input_row]; 52 input_row++; 53 outptr = *output_buf++; 54 for (col = 0; col < num_cols; col++) { 55 y = GETJSAMPLE(inptr0[col]); 56 cb = GETJSAMPLE(inptr1[col]); 57 cr = GETJSAMPLE(inptr2[col]); 58 /* Range-limiting is essential due to noise introduced by DCT losses. */ 59 outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; 60 outptr[RGB_GREEN] = range_limit[y + 61 ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], 62 SCALEBITS))]; 63 outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]]; 64 /* Set unused byte to 0xFF so it can be interpreted as an opaque */ 65 /* alpha channel value */ 66 #ifdef RGB_ALPHA 67 outptr[RGB_ALPHA] = 0xFF; 68 #endif 69 outptr += RGB_PIXELSIZE; 70 } 71 } 72 } 73 74 75 /* 76 * Convert grayscale to RGB: just duplicate the graylevel three times. 77 * This is provided to support applications that don't want to cope 78 * with grayscale as a separate case. 79 */ 80 81 INLINE 82 LOCAL(void) 83 gray_rgb_convert_internal (j_decompress_ptr cinfo, 84 JSAMPIMAGE input_buf, JDIMENSION input_row, 85 JSAMPARRAY output_buf, int num_rows) 86 { 87 register JSAMPROW inptr, outptr; 88 register JDIMENSION col; 89 JDIMENSION num_cols = cinfo->output_width; 90 91 while (--num_rows >= 0) { 92 inptr = input_buf[0][input_row++]; 93 outptr = *output_buf++; 94 for (col = 0; col < num_cols; col++) { 95 /* We can dispense with GETJSAMPLE() here */ 96 outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col]; 97 /* Set unused byte to 0xFF so it can be interpreted as an opaque */ 98 /* alpha channel value */ 99 #ifdef RGB_ALPHA 100 outptr[RGB_ALPHA] = 0xFF; 101 #endif 102 outptr += RGB_PIXELSIZE; 103 } 104 } 105 } 106 107 108 /* 109 * Convert RGB to extended RGB: just swap the order of source pixels 110 */ 111 112 INLINE 113 LOCAL(void) 114 rgb_rgb_convert_internal (j_decompress_ptr cinfo, 115 JSAMPIMAGE input_buf, JDIMENSION input_row, 116 JSAMPARRAY output_buf, int num_rows) 117 { 118 register JSAMPROW inptr0, inptr1, inptr2; 119 register JSAMPROW outptr; 120 register JDIMENSION col; 121 JDIMENSION num_cols = cinfo->output_width; 122 123 while (--num_rows >= 0) { 124 inptr0 = input_buf[0][input_row]; 125 inptr1 = input_buf[1][input_row]; 126 inptr2 = input_buf[2][input_row]; 127 input_row++; 128 outptr = *output_buf++; 129 for (col = 0; col < num_cols; col++) { 130 /* We can dispense with GETJSAMPLE() here */ 131 outptr[RGB_RED] = inptr0[col]; 132 outptr[RGB_GREEN] = inptr1[col]; 133 outptr[RGB_BLUE] = inptr2[col]; 134 /* Set unused byte to 0xFF so it can be interpreted as an opaque */ 135 /* alpha channel value */ 136 #ifdef RGB_ALPHA 137 outptr[RGB_ALPHA] = 0xFF; 138 #endif 139 outptr += RGB_PIXELSIZE; 140 } 141 } 142 } 143