jdmerge.c (19979B)
1 /* 2 * jdmerge.c 3 * 4 * This file was part of the Independent JPEG Group's software: 5 * Copyright (C) 1994-1996, Thomas G. Lane. 6 * libjpeg-turbo Modifications: 7 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB 8 * Copyright (C) 2009, 2011, 2014-2015, 2020, 2022, D. R. Commander. 9 * Copyright (C) 2013, Linaro Limited. 10 * For conditions of distribution and use, see the accompanying README.ijg 11 * file. 12 * 13 * This file contains code for merged upsampling/color conversion. 14 * 15 * This file combines functions from jdsample.c and jdcolor.c; 16 * read those files first to understand what's going on. 17 * 18 * When the chroma components are to be upsampled by simple replication 19 * (ie, box filtering), we can save some work in color conversion by 20 * calculating all the output pixels corresponding to a pair of chroma 21 * samples at one time. In the conversion equations 22 * R = Y + K1 * Cr 23 * G = Y + K2 * Cb + K3 * Cr 24 * B = Y + K4 * Cb 25 * only the Y term varies among the group of pixels corresponding to a pair 26 * of chroma samples, so the rest of the terms can be calculated just once. 27 * At typical sampling ratios, this eliminates half or three-quarters of the 28 * multiplications needed for color conversion. 29 * 30 * This file currently provides implementations for the following cases: 31 * YCbCr => RGB color conversion only. 32 * Sampling ratios of 2h1v or 2h2v. 33 * No scaling needed at upsample time. 34 * Corner-aligned (non-CCIR601) sampling alignment. 35 * Other special cases could be added, but in most applications these are 36 * the only common cases. (For uncommon cases we fall back on the more 37 * general code in jdsample.c and jdcolor.c.) 38 */ 39 40 #define JPEG_INTERNALS 41 #include "jinclude.h" 42 #include "jpeglib.h" 43 #include "jdmerge.h" 44 #include "jsimd.h" 45 46 #ifdef UPSAMPLE_MERGING_SUPPORTED 47 48 49 #define SCALEBITS 16 /* speediest right-shift on some machines */ 50 #define ONE_HALF ((JLONG)1 << (SCALEBITS - 1)) 51 #define FIX(x) ((JLONG)((x) * (1L << SCALEBITS) + 0.5)) 52 53 54 /* Include inline routines for colorspace extensions */ 55 56 #include "jdmrgext.c" 57 #undef RGB_RED 58 #undef RGB_GREEN 59 #undef RGB_BLUE 60 #undef RGB_PIXELSIZE 61 62 #define RGB_RED EXT_RGB_RED 63 #define RGB_GREEN EXT_RGB_GREEN 64 #define RGB_BLUE EXT_RGB_BLUE 65 #define RGB_PIXELSIZE EXT_RGB_PIXELSIZE 66 #define h2v1_merged_upsample_internal extrgb_h2v1_merged_upsample_internal 67 #define h2v2_merged_upsample_internal extrgb_h2v2_merged_upsample_internal 68 #include "jdmrgext.c" 69 #undef RGB_RED 70 #undef RGB_GREEN 71 #undef RGB_BLUE 72 #undef RGB_PIXELSIZE 73 #undef h2v1_merged_upsample_internal 74 #undef h2v2_merged_upsample_internal 75 76 #define RGB_RED EXT_RGBX_RED 77 #define RGB_GREEN EXT_RGBX_GREEN 78 #define RGB_BLUE EXT_RGBX_BLUE 79 #define RGB_ALPHA 3 80 #define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE 81 #define h2v1_merged_upsample_internal extrgbx_h2v1_merged_upsample_internal 82 #define h2v2_merged_upsample_internal extrgbx_h2v2_merged_upsample_internal 83 #include "jdmrgext.c" 84 #undef RGB_RED 85 #undef RGB_GREEN 86 #undef RGB_BLUE 87 #undef RGB_ALPHA 88 #undef RGB_PIXELSIZE 89 #undef h2v1_merged_upsample_internal 90 #undef h2v2_merged_upsample_internal 91 92 #define RGB_RED EXT_BGR_RED 93 #define RGB_GREEN EXT_BGR_GREEN 94 #define RGB_BLUE EXT_BGR_BLUE 95 #define RGB_PIXELSIZE EXT_BGR_PIXELSIZE 96 #define h2v1_merged_upsample_internal extbgr_h2v1_merged_upsample_internal 97 #define h2v2_merged_upsample_internal extbgr_h2v2_merged_upsample_internal 98 #include "jdmrgext.c" 99 #undef RGB_RED 100 #undef RGB_GREEN 101 #undef RGB_BLUE 102 #undef RGB_PIXELSIZE 103 #undef h2v1_merged_upsample_internal 104 #undef h2v2_merged_upsample_internal 105 106 #define RGB_RED EXT_BGRX_RED 107 #define RGB_GREEN EXT_BGRX_GREEN 108 #define RGB_BLUE EXT_BGRX_BLUE 109 #define RGB_ALPHA 3 110 #define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE 111 #define h2v1_merged_upsample_internal extbgrx_h2v1_merged_upsample_internal 112 #define h2v2_merged_upsample_internal extbgrx_h2v2_merged_upsample_internal 113 #include "jdmrgext.c" 114 #undef RGB_RED 115 #undef RGB_GREEN 116 #undef RGB_BLUE 117 #undef RGB_ALPHA 118 #undef RGB_PIXELSIZE 119 #undef h2v1_merged_upsample_internal 120 #undef h2v2_merged_upsample_internal 121 122 #define RGB_RED EXT_XBGR_RED 123 #define RGB_GREEN EXT_XBGR_GREEN 124 #define RGB_BLUE EXT_XBGR_BLUE 125 #define RGB_ALPHA 0 126 #define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE 127 #define h2v1_merged_upsample_internal extxbgr_h2v1_merged_upsample_internal 128 #define h2v2_merged_upsample_internal extxbgr_h2v2_merged_upsample_internal 129 #include "jdmrgext.c" 130 #undef RGB_RED 131 #undef RGB_GREEN 132 #undef RGB_BLUE 133 #undef RGB_ALPHA 134 #undef RGB_PIXELSIZE 135 #undef h2v1_merged_upsample_internal 136 #undef h2v2_merged_upsample_internal 137 138 #define RGB_RED EXT_XRGB_RED 139 #define RGB_GREEN EXT_XRGB_GREEN 140 #define RGB_BLUE EXT_XRGB_BLUE 141 #define RGB_ALPHA 0 142 #define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE 143 #define h2v1_merged_upsample_internal extxrgb_h2v1_merged_upsample_internal 144 #define h2v2_merged_upsample_internal extxrgb_h2v2_merged_upsample_internal 145 #include "jdmrgext.c" 146 #undef RGB_RED 147 #undef RGB_GREEN 148 #undef RGB_BLUE 149 #undef RGB_ALPHA 150 #undef RGB_PIXELSIZE 151 #undef h2v1_merged_upsample_internal 152 #undef h2v2_merged_upsample_internal 153 154 155 /* 156 * Initialize tables for YCC->RGB colorspace conversion. 157 * This is taken directly from jdcolor.c; see that file for more info. 158 */ 159 160 LOCAL(void) 161 build_ycc_rgb_table(j_decompress_ptr cinfo) 162 { 163 my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample; 164 int i; 165 JLONG x; 166 SHIFT_TEMPS 167 168 upsample->Cr_r_tab = (int *) 169 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, 170 (_MAXJSAMPLE + 1) * sizeof(int)); 171 upsample->Cb_b_tab = (int *) 172 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, 173 (_MAXJSAMPLE + 1) * sizeof(int)); 174 upsample->Cr_g_tab = (JLONG *) 175 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, 176 (_MAXJSAMPLE + 1) * sizeof(JLONG)); 177 upsample->Cb_g_tab = (JLONG *) 178 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, 179 (_MAXJSAMPLE + 1) * sizeof(JLONG)); 180 181 for (i = 0, x = -_CENTERJSAMPLE; i <= _MAXJSAMPLE; i++, x++) { 182 /* i is the actual input pixel value, in the range 0.._MAXJSAMPLE */ 183 /* The Cb or Cr value we are thinking of is x = i - _CENTERJSAMPLE */ 184 /* Cr=>R value is nearest int to 1.40200 * x */ 185 upsample->Cr_r_tab[i] = (int) 186 RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS); 187 /* Cb=>B value is nearest int to 1.77200 * x */ 188 upsample->Cb_b_tab[i] = (int) 189 RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS); 190 /* Cr=>G value is scaled-up -0.71414 * x */ 191 upsample->Cr_g_tab[i] = (-FIX(0.71414)) * x; 192 /* Cb=>G value is scaled-up -0.34414 * x */ 193 /* We also add in ONE_HALF so that need not do it in inner loop */ 194 upsample->Cb_g_tab[i] = (-FIX(0.34414)) * x + ONE_HALF; 195 } 196 } 197 198 199 /* 200 * Initialize for an upsampling pass. 201 */ 202 203 METHODDEF(void) 204 start_pass_merged_upsample(j_decompress_ptr cinfo) 205 { 206 my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample; 207 208 /* Mark the spare buffer empty */ 209 upsample->spare_full = FALSE; 210 /* Initialize total-height counter for detecting bottom of image */ 211 upsample->rows_to_go = cinfo->output_height; 212 } 213 214 215 /* 216 * Control routine to do upsampling (and color conversion). 217 * 218 * The control routine just handles the row buffering considerations. 219 */ 220 221 METHODDEF(void) 222 merged_2v_upsample(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 223 JDIMENSION *in_row_group_ctr, 224 JDIMENSION in_row_groups_avail, _JSAMPARRAY output_buf, 225 JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail) 226 /* 2:1 vertical sampling case: may need a spare row. */ 227 { 228 my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample; 229 _JSAMPROW work_ptrs[2]; 230 JDIMENSION num_rows; /* number of rows returned to caller */ 231 232 if (upsample->spare_full) { 233 /* If we have a spare row saved from a previous cycle, just return it. */ 234 JDIMENSION size = upsample->out_row_width; 235 if (cinfo->out_color_space == JCS_RGB565) 236 size = cinfo->output_width * 2; 237 _jcopy_sample_rows(&upsample->spare_row, 0, output_buf + *out_row_ctr, 0, 238 1, size); 239 num_rows = 1; 240 upsample->spare_full = FALSE; 241 } else { 242 /* Figure number of rows to return to caller. */ 243 num_rows = 2; 244 /* Not more than the distance to the end of the image. */ 245 if (num_rows > upsample->rows_to_go) 246 num_rows = upsample->rows_to_go; 247 /* And not more than what the client can accept: */ 248 out_rows_avail -= *out_row_ctr; 249 if (num_rows > out_rows_avail) 250 num_rows = out_rows_avail; 251 /* Create output pointer array for upsampler. */ 252 work_ptrs[0] = output_buf[*out_row_ctr]; 253 if (num_rows > 1) { 254 work_ptrs[1] = output_buf[*out_row_ctr + 1]; 255 } else { 256 work_ptrs[1] = upsample->spare_row; 257 upsample->spare_full = TRUE; 258 } 259 /* Now do the upsampling. */ 260 (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs); 261 } 262 263 /* Adjust counts */ 264 *out_row_ctr += num_rows; 265 upsample->rows_to_go -= num_rows; 266 /* When the buffer is emptied, declare this input row group consumed */ 267 if (!upsample->spare_full) 268 (*in_row_group_ctr)++; 269 } 270 271 272 METHODDEF(void) 273 merged_1v_upsample(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 274 JDIMENSION *in_row_group_ctr, 275 JDIMENSION in_row_groups_avail, _JSAMPARRAY output_buf, 276 JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail) 277 /* 1:1 vertical sampling case: much easier, never need a spare row. */ 278 { 279 my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample; 280 281 /* Just do the upsampling. */ 282 (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, 283 output_buf + *out_row_ctr); 284 /* Adjust counts */ 285 (*out_row_ctr)++; 286 (*in_row_group_ctr)++; 287 } 288 289 290 /* 291 * These are the routines invoked by the control routines to do 292 * the actual upsampling/conversion. One row group is processed per call. 293 * 294 * Note: since we may be writing directly into application-supplied buffers, 295 * we have to be honest about the output width; we can't assume the buffer 296 * has been rounded up to an even width. 297 */ 298 299 300 /* 301 * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical. 302 */ 303 304 METHODDEF(void) 305 h2v1_merged_upsample(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 306 JDIMENSION in_row_group_ctr, _JSAMPARRAY output_buf) 307 { 308 switch (cinfo->out_color_space) { 309 case JCS_EXT_RGB: 310 extrgb_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr, 311 output_buf); 312 break; 313 case JCS_EXT_RGBX: 314 case JCS_EXT_RGBA: 315 extrgbx_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr, 316 output_buf); 317 break; 318 case JCS_EXT_BGR: 319 extbgr_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr, 320 output_buf); 321 break; 322 case JCS_EXT_BGRX: 323 case JCS_EXT_BGRA: 324 extbgrx_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr, 325 output_buf); 326 break; 327 case JCS_EXT_XBGR: 328 case JCS_EXT_ABGR: 329 extxbgr_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr, 330 output_buf); 331 break; 332 case JCS_EXT_XRGB: 333 case JCS_EXT_ARGB: 334 extxrgb_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr, 335 output_buf); 336 break; 337 default: 338 h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr, 339 output_buf); 340 break; 341 } 342 } 343 344 345 /* 346 * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical. 347 */ 348 349 METHODDEF(void) 350 h2v2_merged_upsample(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 351 JDIMENSION in_row_group_ctr, _JSAMPARRAY output_buf) 352 { 353 switch (cinfo->out_color_space) { 354 case JCS_EXT_RGB: 355 extrgb_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr, 356 output_buf); 357 break; 358 case JCS_EXT_RGBX: 359 case JCS_EXT_RGBA: 360 extrgbx_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr, 361 output_buf); 362 break; 363 case JCS_EXT_BGR: 364 extbgr_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr, 365 output_buf); 366 break; 367 case JCS_EXT_BGRX: 368 case JCS_EXT_BGRA: 369 extbgrx_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr, 370 output_buf); 371 break; 372 case JCS_EXT_XBGR: 373 case JCS_EXT_ABGR: 374 extxbgr_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr, 375 output_buf); 376 break; 377 case JCS_EXT_XRGB: 378 case JCS_EXT_ARGB: 379 extxrgb_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr, 380 output_buf); 381 break; 382 default: 383 h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr, 384 output_buf); 385 break; 386 } 387 } 388 389 390 /* 391 * RGB565 conversion 392 */ 393 394 #define PACK_SHORT_565_LE(r, g, b) \ 395 ((((r) << 8) & 0xF800) | (((g) << 3) & 0x7E0) | ((b) >> 3)) 396 #define PACK_SHORT_565_BE(r, g, b) \ 397 (((r) & 0xF8) | ((g) >> 5) | (((g) << 11) & 0xE000) | (((b) << 5) & 0x1F00)) 398 399 #define PACK_TWO_PIXELS_LE(l, r) ((r << 16) | l) 400 #define PACK_TWO_PIXELS_BE(l, r) ((l << 16) | r) 401 402 #define WRITE_TWO_PIXELS_LE(addr, pixels) { \ 403 ((INT16 *)(addr))[0] = (INT16)(pixels); \ 404 ((INT16 *)(addr))[1] = (INT16)((pixels) >> 16); \ 405 } 406 #define WRITE_TWO_PIXELS_BE(addr, pixels) { \ 407 ((INT16 *)(addr))[1] = (INT16)(pixels); \ 408 ((INT16 *)(addr))[0] = (INT16)((pixels) >> 16); \ 409 } 410 411 #define DITHER_565_R(r, dither) ((r) + ((dither) & 0xFF)) 412 #define DITHER_565_G(g, dither) ((g) + (((dither) & 0xFF) >> 1)) 413 #define DITHER_565_B(b, dither) ((b) + ((dither) & 0xFF)) 414 415 416 /* Declarations for ordered dithering 417 * 418 * We use a 4x4 ordered dither array packed into 32 bits. This array is 419 * sufficient for dithering RGB888 to RGB565. 420 */ 421 422 #define DITHER_MASK 0x3 423 #define DITHER_ROTATE(x) ((((x) & 0xFF) << 24) | (((x) >> 8) & 0x00FFFFFF)) 424 static const JLONG dither_matrix[4] = { 425 0x0008020A, 426 0x0C040E06, 427 0x030B0109, 428 0x0F070D05 429 }; 430 431 432 /* Include inline routines for RGB565 conversion */ 433 434 #define PACK_SHORT_565 PACK_SHORT_565_LE 435 #define PACK_TWO_PIXELS PACK_TWO_PIXELS_LE 436 #define WRITE_TWO_PIXELS WRITE_TWO_PIXELS_LE 437 #define h2v1_merged_upsample_565_internal h2v1_merged_upsample_565_le 438 #define h2v1_merged_upsample_565D_internal h2v1_merged_upsample_565D_le 439 #define h2v2_merged_upsample_565_internal h2v2_merged_upsample_565_le 440 #define h2v2_merged_upsample_565D_internal h2v2_merged_upsample_565D_le 441 #include "jdmrg565.c" 442 #undef PACK_SHORT_565 443 #undef PACK_TWO_PIXELS 444 #undef WRITE_TWO_PIXELS 445 #undef h2v1_merged_upsample_565_internal 446 #undef h2v1_merged_upsample_565D_internal 447 #undef h2v2_merged_upsample_565_internal 448 #undef h2v2_merged_upsample_565D_internal 449 450 #define PACK_SHORT_565 PACK_SHORT_565_BE 451 #define PACK_TWO_PIXELS PACK_TWO_PIXELS_BE 452 #define WRITE_TWO_PIXELS WRITE_TWO_PIXELS_BE 453 #define h2v1_merged_upsample_565_internal h2v1_merged_upsample_565_be 454 #define h2v1_merged_upsample_565D_internal h2v1_merged_upsample_565D_be 455 #define h2v2_merged_upsample_565_internal h2v2_merged_upsample_565_be 456 #define h2v2_merged_upsample_565D_internal h2v2_merged_upsample_565D_be 457 #include "jdmrg565.c" 458 #undef PACK_SHORT_565 459 #undef PACK_TWO_PIXELS 460 #undef WRITE_TWO_PIXELS 461 #undef h2v1_merged_upsample_565_internal 462 #undef h2v1_merged_upsample_565D_internal 463 #undef h2v2_merged_upsample_565_internal 464 #undef h2v2_merged_upsample_565D_internal 465 466 467 static INLINE boolean is_big_endian(void) 468 { 469 int test_value = 1; 470 if (*(char *)&test_value != 1) 471 return TRUE; 472 return FALSE; 473 } 474 475 476 METHODDEF(void) 477 h2v1_merged_upsample_565(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 478 JDIMENSION in_row_group_ctr, _JSAMPARRAY output_buf) 479 { 480 if (is_big_endian()) 481 h2v1_merged_upsample_565_be(cinfo, input_buf, in_row_group_ctr, 482 output_buf); 483 else 484 h2v1_merged_upsample_565_le(cinfo, input_buf, in_row_group_ctr, 485 output_buf); 486 } 487 488 489 METHODDEF(void) 490 h2v1_merged_upsample_565D(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 491 JDIMENSION in_row_group_ctr, _JSAMPARRAY output_buf) 492 { 493 if (is_big_endian()) 494 h2v1_merged_upsample_565D_be(cinfo, input_buf, in_row_group_ctr, 495 output_buf); 496 else 497 h2v1_merged_upsample_565D_le(cinfo, input_buf, in_row_group_ctr, 498 output_buf); 499 } 500 501 502 METHODDEF(void) 503 h2v2_merged_upsample_565(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 504 JDIMENSION in_row_group_ctr, _JSAMPARRAY output_buf) 505 { 506 if (is_big_endian()) 507 h2v2_merged_upsample_565_be(cinfo, input_buf, in_row_group_ctr, 508 output_buf); 509 else 510 h2v2_merged_upsample_565_le(cinfo, input_buf, in_row_group_ctr, 511 output_buf); 512 } 513 514 515 METHODDEF(void) 516 h2v2_merged_upsample_565D(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 517 JDIMENSION in_row_group_ctr, _JSAMPARRAY output_buf) 518 { 519 if (is_big_endian()) 520 h2v2_merged_upsample_565D_be(cinfo, input_buf, in_row_group_ctr, 521 output_buf); 522 else 523 h2v2_merged_upsample_565D_le(cinfo, input_buf, in_row_group_ctr, 524 output_buf); 525 } 526 527 528 /* 529 * Module initialization routine for merged upsampling/color conversion. 530 * 531 * NB: this is called under the conditions determined by use_merged_upsample() 532 * in jdmaster.c. That routine MUST correspond to the actual capabilities 533 * of this module; no safety checks are made here. 534 */ 535 536 GLOBAL(void) 537 _jinit_merged_upsampler(j_decompress_ptr cinfo) 538 { 539 my_merged_upsample_ptr upsample; 540 541 if (cinfo->data_precision != BITS_IN_JSAMPLE) 542 ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); 543 544 upsample = (my_merged_upsample_ptr) 545 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, 546 sizeof(my_merged_upsampler)); 547 cinfo->upsample = (struct jpeg_upsampler *)upsample; 548 upsample->pub.start_pass = start_pass_merged_upsample; 549 upsample->pub.need_context_rows = FALSE; 550 551 upsample->out_row_width = cinfo->output_width * cinfo->out_color_components; 552 553 if (cinfo->max_v_samp_factor == 2) { 554 upsample->pub._upsample = merged_2v_upsample; 555 #ifdef WITH_SIMD 556 if (jsimd_can_h2v2_merged_upsample()) 557 upsample->upmethod = jsimd_h2v2_merged_upsample; 558 else 559 #endif 560 upsample->upmethod = h2v2_merged_upsample; 561 if (cinfo->out_color_space == JCS_RGB565) { 562 if (cinfo->dither_mode != JDITHER_NONE) { 563 upsample->upmethod = h2v2_merged_upsample_565D; 564 } else { 565 upsample->upmethod = h2v2_merged_upsample_565; 566 } 567 } 568 /* Allocate a spare row buffer */ 569 upsample->spare_row = (_JSAMPROW) 570 (*cinfo->mem->alloc_large) ((j_common_ptr)cinfo, JPOOL_IMAGE, 571 (size_t)(upsample->out_row_width * sizeof(_JSAMPLE))); 572 } else { 573 upsample->pub._upsample = merged_1v_upsample; 574 #ifdef WITH_SIMD 575 if (jsimd_can_h2v1_merged_upsample()) 576 upsample->upmethod = jsimd_h2v1_merged_upsample; 577 else 578 #endif 579 upsample->upmethod = h2v1_merged_upsample; 580 if (cinfo->out_color_space == JCS_RGB565) { 581 if (cinfo->dither_mode != JDITHER_NONE) { 582 upsample->upmethod = h2v1_merged_upsample_565D; 583 } else { 584 upsample->upmethod = h2v1_merged_upsample_565; 585 } 586 } 587 /* No spare row needed */ 588 upsample->spare_row = NULL; 589 } 590 591 build_ycc_rgb_table(cinfo); 592 } 593 594 #endif /* UPSAMPLE_MERGING_SUPPORTED */