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