blob: dff5a350870cc4740a7e5b22ead53ae1129c76c2 [file] [log] [blame]
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +00001/*
2 * jdmerge.c
3 *
DRCa73e8702012-12-31 02:52:30 +00004 * This file was part of the Independent JPEG Group's software:
Thomas G. Lane489583f1996-02-07 00:00:00 +00005 * Copyright (C) 1994-1996, Thomas G. Lane.
DRCa6ef2822013-09-28 03:23:49 +00006 * libjpeg-turbo Modifications:
DRC9100b672016-02-19 09:25:44 -06007 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
DRC1e32fe32015-10-14 17:32:39 -05008 * Copyright (C) 2009, 2011, 2014-2015, D. R. Commander.
DRC78df2e62014-05-12 09:23:57 +00009 * Copyright (C) 2013, Linaro Limited.
DRC7e3acc02015-10-10 10:25:46 -050010 * For conditions of distribution and use, see the accompanying README.ijg
11 * file.
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000012 *
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
DRCe5eaf372014-05-09 18:00:32 +000022 * R = Y + K1 * Cr
23 * G = Y + K2 * Cb + K3 * Cr
24 * B = Y + K4 * Cb
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000025 * 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:
DRCe5eaf372014-05-09 18:00:32 +000031 * 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.
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000035 * 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"
Pierre Ossman59a39382009-03-09 13:15:56 +000043#include "jsimd.h"
DRCff6961f2014-04-20 09:17:11 +000044#include "jconfigint.h"
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000045
46#ifdef UPSAMPLE_MERGING_SUPPORTED
47
48
49/* Private subobject */
50
51typedef struct {
DRCe5eaf372014-05-09 18:00:32 +000052 struct jpeg_upsampler pub; /* public fields */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000053
54 /* Pointer to routine to do actual upsampling/conversion of one row group */
DRCbc56b752014-05-16 10:43:44 +000055 void (*upmethod) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
56 JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000057
58 /* Private state for YCC->RGB conversion */
DRCbd498032016-02-19 08:53:33 -060059 int *Cr_r_tab; /* => table for Cr to R conversion */
60 int *Cb_b_tab; /* => table for Cb to B conversion */
61 JLONG *Cr_g_tab; /* => table for Cr to G conversion */
62 JLONG *Cb_g_tab; /* => table for Cb to G conversion */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000063
64 /* For 2:1 vertical sampling, we produce two output rows at a time.
65 * We need a "spare" row buffer to hold the second output row if the
66 * application provides just a one-row buffer; we also use the spare
67 * to discard the dummy last row if the image height is odd.
68 */
69 JSAMPROW spare_row;
DRCe5eaf372014-05-09 18:00:32 +000070 boolean spare_full; /* T if spare buffer is occupied */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000071
DRCe5eaf372014-05-09 18:00:32 +000072 JDIMENSION out_row_width; /* samples per output row */
73 JDIMENSION rows_to_go; /* counts rows remaining in image */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000074} my_upsampler;
75
DRCbd498032016-02-19 08:53:33 -060076typedef my_upsampler *my_upsample_ptr;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000077
DRCe5eaf372014-05-09 18:00:32 +000078#define SCALEBITS 16 /* speediest right-shift on some machines */
DRC19c791c2018-03-08 10:55:20 -060079#define ONE_HALF ((JLONG)1 << (SCALEBITS - 1))
80#define FIX(x) ((JLONG)((x) * (1L << SCALEBITS) + 0.5))
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000081
82
DRCb4570bb2011-09-07 06:31:00 +000083/* Include inline routines for colorspace extensions */
84
85#include "jdmrgext.c"
86#undef RGB_RED
87#undef RGB_GREEN
88#undef RGB_BLUE
89#undef RGB_PIXELSIZE
90
DRC293263c2018-03-17 15:14:35 -050091#define RGB_RED EXT_RGB_RED
92#define RGB_GREEN EXT_RGB_GREEN
93#define RGB_BLUE EXT_RGB_BLUE
94#define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
95#define h2v1_merged_upsample_internal extrgb_h2v1_merged_upsample_internal
96#define h2v2_merged_upsample_internal extrgb_h2v2_merged_upsample_internal
DRCb4570bb2011-09-07 06:31:00 +000097#include "jdmrgext.c"
98#undef RGB_RED
99#undef RGB_GREEN
100#undef RGB_BLUE
101#undef RGB_PIXELSIZE
102#undef h2v1_merged_upsample_internal
103#undef h2v2_merged_upsample_internal
104
DRC293263c2018-03-17 15:14:35 -0500105#define RGB_RED EXT_RGBX_RED
106#define RGB_GREEN EXT_RGBX_GREEN
107#define RGB_BLUE EXT_RGBX_BLUE
108#define RGB_ALPHA 3
109#define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
110#define h2v1_merged_upsample_internal extrgbx_h2v1_merged_upsample_internal
111#define h2v2_merged_upsample_internal extrgbx_h2v2_merged_upsample_internal
DRCb4570bb2011-09-07 06:31:00 +0000112#include "jdmrgext.c"
113#undef RGB_RED
114#undef RGB_GREEN
115#undef RGB_BLUE
DRCcac10512012-03-16 14:37:36 +0000116#undef RGB_ALPHA
DRCb4570bb2011-09-07 06:31:00 +0000117#undef RGB_PIXELSIZE
118#undef h2v1_merged_upsample_internal
119#undef h2v2_merged_upsample_internal
120
DRC293263c2018-03-17 15:14:35 -0500121#define RGB_RED EXT_BGR_RED
122#define RGB_GREEN EXT_BGR_GREEN
123#define RGB_BLUE EXT_BGR_BLUE
124#define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
125#define h2v1_merged_upsample_internal extbgr_h2v1_merged_upsample_internal
126#define h2v2_merged_upsample_internal extbgr_h2v2_merged_upsample_internal
DRCb4570bb2011-09-07 06:31:00 +0000127#include "jdmrgext.c"
128#undef RGB_RED
129#undef RGB_GREEN
130#undef RGB_BLUE
131#undef RGB_PIXELSIZE
132#undef h2v1_merged_upsample_internal
133#undef h2v2_merged_upsample_internal
134
DRC293263c2018-03-17 15:14:35 -0500135#define RGB_RED EXT_BGRX_RED
136#define RGB_GREEN EXT_BGRX_GREEN
137#define RGB_BLUE EXT_BGRX_BLUE
138#define RGB_ALPHA 3
139#define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
140#define h2v1_merged_upsample_internal extbgrx_h2v1_merged_upsample_internal
141#define h2v2_merged_upsample_internal extbgrx_h2v2_merged_upsample_internal
DRCb4570bb2011-09-07 06:31:00 +0000142#include "jdmrgext.c"
143#undef RGB_RED
144#undef RGB_GREEN
145#undef RGB_BLUE
DRCcac10512012-03-16 14:37:36 +0000146#undef RGB_ALPHA
DRCb4570bb2011-09-07 06:31:00 +0000147#undef RGB_PIXELSIZE
148#undef h2v1_merged_upsample_internal
149#undef h2v2_merged_upsample_internal
150
DRC293263c2018-03-17 15:14:35 -0500151#define RGB_RED EXT_XBGR_RED
152#define RGB_GREEN EXT_XBGR_GREEN
153#define RGB_BLUE EXT_XBGR_BLUE
154#define RGB_ALPHA 0
155#define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
156#define h2v1_merged_upsample_internal extxbgr_h2v1_merged_upsample_internal
157#define h2v2_merged_upsample_internal extxbgr_h2v2_merged_upsample_internal
DRCb4570bb2011-09-07 06:31:00 +0000158#include "jdmrgext.c"
159#undef RGB_RED
160#undef RGB_GREEN
161#undef RGB_BLUE
DRCcac10512012-03-16 14:37:36 +0000162#undef RGB_ALPHA
DRCb4570bb2011-09-07 06:31:00 +0000163#undef RGB_PIXELSIZE
164#undef h2v1_merged_upsample_internal
165#undef h2v2_merged_upsample_internal
166
DRC293263c2018-03-17 15:14:35 -0500167#define RGB_RED EXT_XRGB_RED
168#define RGB_GREEN EXT_XRGB_GREEN
169#define RGB_BLUE EXT_XRGB_BLUE
170#define RGB_ALPHA 0
171#define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
172#define h2v1_merged_upsample_internal extxrgb_h2v1_merged_upsample_internal
173#define h2v2_merged_upsample_internal extxrgb_h2v2_merged_upsample_internal
DRCb4570bb2011-09-07 06:31:00 +0000174#include "jdmrgext.c"
175#undef RGB_RED
176#undef RGB_GREEN
177#undef RGB_BLUE
DRCcac10512012-03-16 14:37:36 +0000178#undef RGB_ALPHA
DRCb4570bb2011-09-07 06:31:00 +0000179#undef RGB_PIXELSIZE
180#undef h2v1_merged_upsample_internal
181#undef h2v2_merged_upsample_internal
182
183
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000184/*
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000185 * Initialize tables for YCC->RGB colorspace conversion.
186 * This is taken directly from jdcolor.c; see that file for more info.
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000187 */
188
Thomas G. Lane489583f1996-02-07 00:00:00 +0000189LOCAL(void)
DRC19c791c2018-03-08 10:55:20 -0600190build_ycc_rgb_table(j_decompress_ptr cinfo)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000191{
DRC19c791c2018-03-08 10:55:20 -0600192 my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000193 int i;
DRC1e32fe32015-10-14 17:32:39 -0500194 JLONG x;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000195 SHIFT_TEMPS
196
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000197 upsample->Cr_r_tab = (int *)
DRC19c791c2018-03-08 10:55:20 -0600198 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
199 (MAXJSAMPLE + 1) * sizeof(int));
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000200 upsample->Cb_b_tab = (int *)
DRC19c791c2018-03-08 10:55:20 -0600201 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
202 (MAXJSAMPLE + 1) * sizeof(int));
DRC1e32fe32015-10-14 17:32:39 -0500203 upsample->Cr_g_tab = (JLONG *)
DRC19c791c2018-03-08 10:55:20 -0600204 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
205 (MAXJSAMPLE + 1) * sizeof(JLONG));
DRC1e32fe32015-10-14 17:32:39 -0500206 upsample->Cb_g_tab = (JLONG *)
DRC19c791c2018-03-08 10:55:20 -0600207 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
208 (MAXJSAMPLE + 1) * sizeof(JLONG));
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000209
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +0000210 for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000211 /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +0000212 /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000213 /* Cr=>R value is nearest int to 1.40200 * x */
214 upsample->Cr_r_tab[i] = (int)
DRCe5eaf372014-05-09 18:00:32 +0000215 RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000216 /* Cb=>B value is nearest int to 1.77200 * x */
217 upsample->Cb_b_tab[i] = (int)
DRCe5eaf372014-05-09 18:00:32 +0000218 RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000219 /* Cr=>G value is scaled-up -0.71414 * x */
DRC19c791c2018-03-08 10:55:20 -0600220 upsample->Cr_g_tab[i] = (-FIX(0.71414)) * x;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000221 /* Cb=>G value is scaled-up -0.34414 * x */
222 /* We also add in ONE_HALF so that need not do it in inner loop */
DRC19c791c2018-03-08 10:55:20 -0600223 upsample->Cb_g_tab[i] = (-FIX(0.34414)) * x + ONE_HALF;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000224 }
225}
226
227
228/*
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000229 * Initialize for an upsampling pass.
230 */
231
Thomas G. Lane489583f1996-02-07 00:00:00 +0000232METHODDEF(void)
DRC19c791c2018-03-08 10:55:20 -0600233start_pass_merged_upsample(j_decompress_ptr cinfo)
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000234{
DRC19c791c2018-03-08 10:55:20 -0600235 my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000236
237 /* Mark the spare buffer empty */
238 upsample->spare_full = FALSE;
239 /* Initialize total-height counter for detecting bottom of image */
240 upsample->rows_to_go = cinfo->output_height;
241}
242
243
244/*
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000245 * Control routine to do upsampling (and color conversion).
246 *
247 * The control routine just handles the row buffering considerations.
248 */
249
Thomas G. Lane489583f1996-02-07 00:00:00 +0000250METHODDEF(void)
DRC19c791c2018-03-08 10:55:20 -0600251merged_2v_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
252 JDIMENSION *in_row_group_ctr,
253 JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf,
254 JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000255/* 2:1 vertical sampling case: may need a spare row. */
256{
DRC19c791c2018-03-08 10:55:20 -0600257 my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000258 JSAMPROW work_ptrs[2];
DRCe5eaf372014-05-09 18:00:32 +0000259 JDIMENSION num_rows; /* number of rows returned to caller */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000260
261 if (upsample->spare_full) {
262 /* If we have a spare row saved from a previous cycle, just return it. */
DRC78df2e62014-05-12 09:23:57 +0000263 JDIMENSION size = upsample->out_row_width;
264 if (cinfo->out_color_space == JCS_RGB565)
265 size = cinfo->output_width * 2;
DRC19c791c2018-03-08 10:55:20 -0600266 jcopy_sample_rows(&upsample->spare_row, 0, output_buf + *out_row_ctr, 0, 1,
267 size);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000268 num_rows = 1;
269 upsample->spare_full = FALSE;
270 } else {
271 /* Figure number of rows to return to caller. */
272 num_rows = 2;
273 /* Not more than the distance to the end of the image. */
274 if (num_rows > upsample->rows_to_go)
275 num_rows = upsample->rows_to_go;
276 /* And not more than what the client can accept: */
277 out_rows_avail -= *out_row_ctr;
278 if (num_rows > out_rows_avail)
279 num_rows = out_rows_avail;
280 /* Create output pointer array for upsampler. */
281 work_ptrs[0] = output_buf[*out_row_ctr];
282 if (num_rows > 1) {
283 work_ptrs[1] = output_buf[*out_row_ctr + 1];
284 } else {
285 work_ptrs[1] = upsample->spare_row;
286 upsample->spare_full = TRUE;
287 }
288 /* Now do the upsampling. */
289 (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
290 }
291
292 /* Adjust counts */
293 *out_row_ctr += num_rows;
294 upsample->rows_to_go -= num_rows;
295 /* When the buffer is emptied, declare this input row group consumed */
DRC19c791c2018-03-08 10:55:20 -0600296 if (!upsample->spare_full)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000297 (*in_row_group_ctr)++;
298}
299
300
Thomas G. Lane489583f1996-02-07 00:00:00 +0000301METHODDEF(void)
DRC19c791c2018-03-08 10:55:20 -0600302merged_1v_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
303 JDIMENSION *in_row_group_ctr,
304 JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf,
305 JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000306/* 1:1 vertical sampling case: much easier, never need a spare row. */
307{
DRC19c791c2018-03-08 10:55:20 -0600308 my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000309
310 /* Just do the upsampling. */
311 (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
DRCe5eaf372014-05-09 18:00:32 +0000312 output_buf + *out_row_ctr);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000313 /* Adjust counts */
314 (*out_row_ctr)++;
315 (*in_row_group_ctr)++;
316}
317
318
319/*
320 * These are the routines invoked by the control routines to do
321 * the actual upsampling/conversion. One row group is processed per call.
322 *
323 * Note: since we may be writing directly into application-supplied buffers,
324 * we have to be honest about the output width; we can't assume the buffer
325 * has been rounded up to an even width.
326 */
327
328
329/*
330 * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
331 */
332
Thomas G. Lane489583f1996-02-07 00:00:00 +0000333METHODDEF(void)
DRC19c791c2018-03-08 10:55:20 -0600334h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
335 JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000336{
DRCb4570bb2011-09-07 06:31:00 +0000337 switch (cinfo->out_color_space) {
DRC19c791c2018-03-08 10:55:20 -0600338 case JCS_EXT_RGB:
339 extrgb_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
340 output_buf);
341 break;
342 case JCS_EXT_RGBX:
343 case JCS_EXT_RGBA:
344 extrgbx_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
345 output_buf);
346 break;
347 case JCS_EXT_BGR:
348 extbgr_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
349 output_buf);
350 break;
351 case JCS_EXT_BGRX:
352 case JCS_EXT_BGRA:
353 extbgrx_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
354 output_buf);
355 break;
356 case JCS_EXT_XBGR:
357 case JCS_EXT_ABGR:
358 extxbgr_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
359 output_buf);
360 break;
361 case JCS_EXT_XRGB:
362 case JCS_EXT_ARGB:
363 extxrgb_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
364 output_buf);
365 break;
366 default:
367 h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
368 output_buf);
369 break;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000370 }
371}
372
373
374/*
375 * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
376 */
377
Thomas G. Lane489583f1996-02-07 00:00:00 +0000378METHODDEF(void)
DRC19c791c2018-03-08 10:55:20 -0600379h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
380 JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000381{
DRCb4570bb2011-09-07 06:31:00 +0000382 switch (cinfo->out_color_space) {
DRC19c791c2018-03-08 10:55:20 -0600383 case JCS_EXT_RGB:
384 extrgb_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
385 output_buf);
386 break;
387 case JCS_EXT_RGBX:
388 case JCS_EXT_RGBA:
389 extrgbx_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
390 output_buf);
391 break;
392 case JCS_EXT_BGR:
393 extbgr_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
394 output_buf);
395 break;
396 case JCS_EXT_BGRX:
397 case JCS_EXT_BGRA:
398 extbgrx_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
399 output_buf);
400 break;
401 case JCS_EXT_XBGR:
402 case JCS_EXT_ABGR:
403 extxbgr_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
404 output_buf);
405 break;
406 case JCS_EXT_XRGB:
407 case JCS_EXT_ARGB:
408 extxrgb_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
409 output_buf);
410 break;
411 default:
412 h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
413 output_buf);
414 break;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000415 }
416}
417
418
DRC72a3cc02014-08-30 20:37:50 +0000419/*
420 * RGB565 conversion
421 */
422
DRC19c791c2018-03-08 10:55:20 -0600423#define PACK_SHORT_565_LE(r, g, b) ((((r) << 8) & 0xF800) | \
424 (((g) << 3) & 0x7E0) | ((b) >> 3))
425#define PACK_SHORT_565_BE(r, g, b) (((r) & 0xF8) | ((g) >> 5) | \
426 (((g) << 11) & 0xE000) | \
427 (((b) << 5) & 0x1F00))
DRC72a3cc02014-08-30 20:37:50 +0000428
DRC19c791c2018-03-08 10:55:20 -0600429#define PACK_TWO_PIXELS_LE(l, r) ((r << 16) | l)
430#define PACK_TWO_PIXELS_BE(l, r) ((l << 16) | r)
DRC72a3cc02014-08-30 20:37:50 +0000431
DRC19c791c2018-03-08 10:55:20 -0600432#define WRITE_TWO_PIXELS_LE(addr, pixels) { \
433 ((INT16 *)(addr))[0] = (INT16)(pixels); \
434 ((INT16 *)(addr))[1] = (INT16)((pixels) >> 16); \
DRC72a3cc02014-08-30 20:37:50 +0000435}
DRC19c791c2018-03-08 10:55:20 -0600436#define WRITE_TWO_PIXELS_BE(addr, pixels) { \
437 ((INT16 *)(addr))[1] = (INT16)(pixels); \
438 ((INT16 *)(addr))[0] = (INT16)((pixels) >> 16); \
DRC72a3cc02014-08-30 20:37:50 +0000439}
440
DRC72a3cc02014-08-30 20:37:50 +0000441#define DITHER_565_R(r, dither) ((r) + ((dither) & 0xFF))
442#define DITHER_565_G(g, dither) ((g) + (((dither) & 0xFF) >> 1))
443#define DITHER_565_B(b, dither) ((b) + ((dither) & 0xFF))
444
445
446/* Declarations for ordered dithering
447 *
448 * We use a 4x4 ordered dither array packed into 32 bits. This array is
luzpaz43c58ff2018-07-31 21:59:16 +0000449 * sufficient for dithering RGB888 to RGB565.
DRC72a3cc02014-08-30 20:37:50 +0000450 */
451
452#define DITHER_MASK 0x3
DRCd65e7682015-10-14 22:26:25 -0500453#define DITHER_ROTATE(x) ((((x) & 0xFF) << 24) | (((x) >> 8) & 0x00FFFFFF))
DRC1e32fe32015-10-14 17:32:39 -0500454static const JLONG dither_matrix[4] = {
DRC72a3cc02014-08-30 20:37:50 +0000455 0x0008020A,
456 0x0C040E06,
457 0x030B0109,
458 0x0F070D05
459};
460
461
462/* Include inline routines for RGB565 conversion */
463
DRC293263c2018-03-17 15:14:35 -0500464#define PACK_SHORT_565 PACK_SHORT_565_LE
465#define PACK_TWO_PIXELS PACK_TWO_PIXELS_LE
466#define WRITE_TWO_PIXELS WRITE_TWO_PIXELS_LE
467#define h2v1_merged_upsample_565_internal h2v1_merged_upsample_565_le
468#define h2v1_merged_upsample_565D_internal h2v1_merged_upsample_565D_le
469#define h2v2_merged_upsample_565_internal h2v2_merged_upsample_565_le
470#define h2v2_merged_upsample_565D_internal h2v2_merged_upsample_565D_le
DRC72a3cc02014-08-30 20:37:50 +0000471#include "jdmrg565.c"
472#undef PACK_SHORT_565
473#undef PACK_TWO_PIXELS
474#undef WRITE_TWO_PIXELS
475#undef h2v1_merged_upsample_565_internal
476#undef h2v1_merged_upsample_565D_internal
477#undef h2v2_merged_upsample_565_internal
478#undef h2v2_merged_upsample_565D_internal
479
DRC293263c2018-03-17 15:14:35 -0500480#define PACK_SHORT_565 PACK_SHORT_565_BE
481#define PACK_TWO_PIXELS PACK_TWO_PIXELS_BE
482#define WRITE_TWO_PIXELS WRITE_TWO_PIXELS_BE
483#define h2v1_merged_upsample_565_internal h2v1_merged_upsample_565_be
484#define h2v1_merged_upsample_565D_internal h2v1_merged_upsample_565D_be
485#define h2v2_merged_upsample_565_internal h2v2_merged_upsample_565_be
486#define h2v2_merged_upsample_565D_internal h2v2_merged_upsample_565D_be
DRC72a3cc02014-08-30 20:37:50 +0000487#include "jdmrg565.c"
488#undef PACK_SHORT_565
489#undef PACK_TWO_PIXELS
490#undef WRITE_TWO_PIXELS
491#undef h2v1_merged_upsample_565_internal
492#undef h2v1_merged_upsample_565D_internal
493#undef h2v2_merged_upsample_565_internal
494#undef h2v2_merged_upsample_565D_internal
495
496
497static INLINE boolean is_big_endian(void)
498{
499 int test_value = 1;
DRC9d9d8fe2017-11-17 18:15:42 -0600500 if (*(char *)&test_value != 1)
DRC72a3cc02014-08-30 20:37:50 +0000501 return TRUE;
502 return FALSE;
503}
504
505
DRC78df2e62014-05-12 09:23:57 +0000506METHODDEF(void)
DRC19c791c2018-03-08 10:55:20 -0600507h2v1_merged_upsample_565(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
508 JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
DRC78df2e62014-05-12 09:23:57 +0000509{
DRC72a3cc02014-08-30 20:37:50 +0000510 if (is_big_endian())
511 h2v1_merged_upsample_565_be(cinfo, input_buf, in_row_group_ctr,
512 output_buf);
513 else
514 h2v1_merged_upsample_565_le(cinfo, input_buf, in_row_group_ctr,
515 output_buf);
DRC19c791c2018-03-08 10:55:20 -0600516}
DRC78df2e62014-05-12 09:23:57 +0000517
518
519METHODDEF(void)
DRC19c791c2018-03-08 10:55:20 -0600520h2v1_merged_upsample_565D(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
521 JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
DRC78df2e62014-05-12 09:23:57 +0000522{
DRC72a3cc02014-08-30 20:37:50 +0000523 if (is_big_endian())
524 h2v1_merged_upsample_565D_be(cinfo, input_buf, in_row_group_ctr,
525 output_buf);
526 else
527 h2v1_merged_upsample_565D_le(cinfo, input_buf, in_row_group_ctr,
528 output_buf);
DRC78df2e62014-05-12 09:23:57 +0000529}
530
531
532METHODDEF(void)
DRC19c791c2018-03-08 10:55:20 -0600533h2v2_merged_upsample_565(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
534 JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
DRC78df2e62014-05-12 09:23:57 +0000535{
DRC72a3cc02014-08-30 20:37:50 +0000536 if (is_big_endian())
537 h2v2_merged_upsample_565_be(cinfo, input_buf, in_row_group_ctr,
538 output_buf);
539 else
540 h2v2_merged_upsample_565_le(cinfo, input_buf, in_row_group_ctr,
541 output_buf);
DRC78df2e62014-05-12 09:23:57 +0000542}
543
544
545METHODDEF(void)
DRC19c791c2018-03-08 10:55:20 -0600546h2v2_merged_upsample_565D(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
547 JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
DRC78df2e62014-05-12 09:23:57 +0000548{
DRC72a3cc02014-08-30 20:37:50 +0000549 if (is_big_endian())
550 h2v2_merged_upsample_565D_be(cinfo, input_buf, in_row_group_ctr,
551 output_buf);
552 else
553 h2v2_merged_upsample_565D_le(cinfo, input_buf, in_row_group_ctr,
554 output_buf);
DRC78df2e62014-05-12 09:23:57 +0000555}
556
557
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000558/*
559 * Module initialization routine for merged upsampling/color conversion.
560 *
561 * NB: this is called under the conditions determined by use_merged_upsample()
562 * in jdmaster.c. That routine MUST correspond to the actual capabilities
563 * of this module; no safety checks are made here.
564 */
565
Thomas G. Lane489583f1996-02-07 00:00:00 +0000566GLOBAL(void)
DRC19c791c2018-03-08 10:55:20 -0600567jinit_merged_upsampler(j_decompress_ptr cinfo)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000568{
569 my_upsample_ptr upsample;
570
571 upsample = (my_upsample_ptr)
DRC19c791c2018-03-08 10:55:20 -0600572 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
DRC5de454b2014-05-18 19:04:03 +0000573 sizeof(my_upsampler));
DRC19c791c2018-03-08 10:55:20 -0600574 cinfo->upsample = (struct jpeg_upsampler *)upsample;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000575 upsample->pub.start_pass = start_pass_merged_upsample;
576 upsample->pub.need_context_rows = FALSE;
577
578 upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
579
580 if (cinfo->max_v_samp_factor == 2) {
581 upsample->pub.upsample = merged_2v_upsample;
Pierre Ossman59a39382009-03-09 13:15:56 +0000582 if (jsimd_can_h2v2_merged_upsample())
583 upsample->upmethod = jsimd_h2v2_merged_upsample;
584 else
585 upsample->upmethod = h2v2_merged_upsample;
DRC78df2e62014-05-12 09:23:57 +0000586 if (cinfo->out_color_space == JCS_RGB565) {
587 if (cinfo->dither_mode != JDITHER_NONE) {
588 upsample->upmethod = h2v2_merged_upsample_565D;
589 } else {
590 upsample->upmethod = h2v2_merged_upsample_565;
591 }
592 }
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000593 /* Allocate a spare row buffer */
594 upsample->spare_row = (JSAMPROW)
DRC19c791c2018-03-08 10:55:20 -0600595 (*cinfo->mem->alloc_large) ((j_common_ptr)cinfo, JPOOL_IMAGE,
596 (size_t)(upsample->out_row_width * sizeof(JSAMPLE)));
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000597 } else {
598 upsample->pub.upsample = merged_1v_upsample;
Pierre Ossman59a39382009-03-09 13:15:56 +0000599 if (jsimd_can_h2v1_merged_upsample())
600 upsample->upmethod = jsimd_h2v1_merged_upsample;
601 else
602 upsample->upmethod = h2v1_merged_upsample;
DRC78df2e62014-05-12 09:23:57 +0000603 if (cinfo->out_color_space == JCS_RGB565) {
604 if (cinfo->dither_mode != JDITHER_NONE) {
605 upsample->upmethod = h2v1_merged_upsample_565D;
606 } else {
607 upsample->upmethod = h2v1_merged_upsample_565;
608 }
609 }
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000610 /* No spare row needed */
611 upsample->spare_row = NULL;
612 }
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000613
614 build_ycc_rgb_table(cinfo);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000615}
616
617#endif /* UPSAMPLE_MERGING_SUPPORTED */