blob: f89d69f56e5d8b381ace8bf7a0fe509bb1559924 [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.
Pierre Ossman59a39382009-03-09 13:15:56 +00006 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
DRCa6ef2822013-09-28 03:23:49 +00007 * libjpeg-turbo Modifications:
DRCb4570bb2011-09-07 06:31:00 +00008 * Copyright (C) 2009, 2011, D. R. Commander.
DRC78df2e62014-05-12 09:23:57 +00009 * Copyright (C) 2013, Linaro Limited.
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000010 * For conditions of distribution and use, see the accompanying README file.
11 *
12 * This file contains code for merged upsampling/color conversion.
13 *
14 * This file combines functions from jdsample.c and jdcolor.c;
15 * read those files first to understand what's going on.
16 *
17 * When the chroma components are to be upsampled by simple replication
18 * (ie, box filtering), we can save some work in color conversion by
19 * calculating all the output pixels corresponding to a pair of chroma
20 * samples at one time. In the conversion equations
DRCe5eaf372014-05-09 18:00:32 +000021 * R = Y + K1 * Cr
22 * G = Y + K2 * Cb + K3 * Cr
23 * B = Y + K4 * Cb
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000024 * only the Y term varies among the group of pixels corresponding to a pair
25 * of chroma samples, so the rest of the terms can be calculated just once.
26 * At typical sampling ratios, this eliminates half or three-quarters of the
27 * multiplications needed for color conversion.
28 *
29 * This file currently provides implementations for the following cases:
DRCe5eaf372014-05-09 18:00:32 +000030 * YCbCr => RGB color conversion only.
31 * Sampling ratios of 2h1v or 2h2v.
32 * No scaling needed at upsample time.
33 * Corner-aligned (non-CCIR601) sampling alignment.
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000034 * Other special cases could be added, but in most applications these are
35 * the only common cases. (For uncommon cases we fall back on the more
36 * general code in jdsample.c and jdcolor.c.)
37 */
38
39#define JPEG_INTERNALS
40#include "jinclude.h"
41#include "jpeglib.h"
Pierre Ossman59a39382009-03-09 13:15:56 +000042#include "jsimd.h"
DRCff6961f2014-04-20 09:17:11 +000043#include "jconfigint.h"
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000044
45#ifdef UPSAMPLE_MERGING_SUPPORTED
46
47
DRC78df2e62014-05-12 09:23:57 +000048#define PACK_SHORT_565(r, g, b) ((((r) << 8) & 0xf800) | \
49 (((g) << 3) & 0x7E0) | ((b) >> 3))
50#define PACK_TWO_PIXELS(l, r) ((r << 16) | l)
51#define PACK_NEED_ALIGNMENT(ptr) (((size_t)(ptr)) & 3)
52
53#define WRITE_TWO_PIXELS(addr, pixels) { \
54 ((INT16*)(addr))[0] = (pixels); \
55 ((INT16*)(addr))[1] = (pixels) >> 16; \
56}
57#define WRITE_TWO_ALIGNED_PIXELS(addr, pixels) ((*(INT32 *)(addr)) = pixels)
58
59#define DITHER_565_R(r, dither) ((r) + ((dither) & 0xFF))
60#define DITHER_565_G(g, dither) ((g) + (((dither) & 0xFF) >> 1))
61#define DITHER_565_B(b, dither) ((b) + ((dither) & 0xFF))
62
63
64/* Declarations for ordered dithering
65 *
66 * We use a 4x4 ordered dither array packed into 32 bits. This array is
67 * sufficent for dithering RGB888 to RGB565.
68 */
69
70#define DITHER_MASK 0x3
71#define DITHER_ROTATE(x) (((x) << 24) | (((x) >> 8) & 0x00FFFFFF))
72static const INT32 dither_matrix[4] = {
73 0x0008020A,
74 0x0C040E06,
75 0x030B0109,
76 0x0F070D05
77};
78
79
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000080/* Private subobject */
81
82typedef struct {
DRCe5eaf372014-05-09 18:00:32 +000083 struct jpeg_upsampler pub; /* public fields */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000084
85 /* Pointer to routine to do actual upsampling/conversion of one row group */
DRCbc56b752014-05-16 10:43:44 +000086 void (*upmethod) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
87 JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000088
89 /* Private state for YCC->RGB conversion */
DRCe5eaf372014-05-09 18:00:32 +000090 int * Cr_r_tab; /* => table for Cr to R conversion */
91 int * Cb_b_tab; /* => table for Cb to B conversion */
92 INT32 * Cr_g_tab; /* => table for Cr to G conversion */
93 INT32 * Cb_g_tab; /* => table for Cb to G conversion */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000094
95 /* For 2:1 vertical sampling, we produce two output rows at a time.
96 * We need a "spare" row buffer to hold the second output row if the
97 * application provides just a one-row buffer; we also use the spare
98 * to discard the dummy last row if the image height is odd.
99 */
100 JSAMPROW spare_row;
DRCe5eaf372014-05-09 18:00:32 +0000101 boolean spare_full; /* T if spare buffer is occupied */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000102
DRCe5eaf372014-05-09 18:00:32 +0000103 JDIMENSION out_row_width; /* samples per output row */
104 JDIMENSION rows_to_go; /* counts rows remaining in image */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000105} my_upsampler;
106
107typedef my_upsampler * my_upsample_ptr;
108
DRCe5eaf372014-05-09 18:00:32 +0000109#define SCALEBITS 16 /* speediest right-shift on some machines */
110#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
111#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000112
113
DRCb4570bb2011-09-07 06:31:00 +0000114/* Include inline routines for colorspace extensions */
115
116#include "jdmrgext.c"
117#undef RGB_RED
118#undef RGB_GREEN
119#undef RGB_BLUE
120#undef RGB_PIXELSIZE
121
122#define RGB_RED EXT_RGB_RED
123#define RGB_GREEN EXT_RGB_GREEN
124#define RGB_BLUE EXT_RGB_BLUE
125#define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
126#define h2v1_merged_upsample_internal extrgb_h2v1_merged_upsample_internal
127#define h2v2_merged_upsample_internal extrgb_h2v2_merged_upsample_internal
128#include "jdmrgext.c"
129#undef RGB_RED
130#undef RGB_GREEN
131#undef RGB_BLUE
132#undef RGB_PIXELSIZE
133#undef h2v1_merged_upsample_internal
134#undef h2v2_merged_upsample_internal
135
136#define RGB_RED EXT_RGBX_RED
137#define RGB_GREEN EXT_RGBX_GREEN
138#define RGB_BLUE EXT_RGBX_BLUE
DRCcac10512012-03-16 14:37:36 +0000139#define RGB_ALPHA 3
DRCb4570bb2011-09-07 06:31:00 +0000140#define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
141#define h2v1_merged_upsample_internal extrgbx_h2v1_merged_upsample_internal
142#define h2v2_merged_upsample_internal extrgbx_h2v2_merged_upsample_internal
143#include "jdmrgext.c"
144#undef RGB_RED
145#undef RGB_GREEN
146#undef RGB_BLUE
DRCcac10512012-03-16 14:37:36 +0000147#undef RGB_ALPHA
DRCb4570bb2011-09-07 06:31:00 +0000148#undef RGB_PIXELSIZE
149#undef h2v1_merged_upsample_internal
150#undef h2v2_merged_upsample_internal
151
152#define RGB_RED EXT_BGR_RED
153#define RGB_GREEN EXT_BGR_GREEN
154#define RGB_BLUE EXT_BGR_BLUE
155#define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
156#define h2v1_merged_upsample_internal extbgr_h2v1_merged_upsample_internal
157#define h2v2_merged_upsample_internal extbgr_h2v2_merged_upsample_internal
158#include "jdmrgext.c"
159#undef RGB_RED
160#undef RGB_GREEN
161#undef RGB_BLUE
162#undef RGB_PIXELSIZE
163#undef h2v1_merged_upsample_internal
164#undef h2v2_merged_upsample_internal
165
166#define RGB_RED EXT_BGRX_RED
167#define RGB_GREEN EXT_BGRX_GREEN
168#define RGB_BLUE EXT_BGRX_BLUE
DRCcac10512012-03-16 14:37:36 +0000169#define RGB_ALPHA 3
DRCb4570bb2011-09-07 06:31:00 +0000170#define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
171#define h2v1_merged_upsample_internal extbgrx_h2v1_merged_upsample_internal
172#define h2v2_merged_upsample_internal extbgrx_h2v2_merged_upsample_internal
173#include "jdmrgext.c"
174#undef RGB_RED
175#undef RGB_GREEN
176#undef RGB_BLUE
DRCcac10512012-03-16 14:37:36 +0000177#undef RGB_ALPHA
DRCb4570bb2011-09-07 06:31:00 +0000178#undef RGB_PIXELSIZE
179#undef h2v1_merged_upsample_internal
180#undef h2v2_merged_upsample_internal
181
182#define RGB_RED EXT_XBGR_RED
183#define RGB_GREEN EXT_XBGR_GREEN
184#define RGB_BLUE EXT_XBGR_BLUE
DRCcac10512012-03-16 14:37:36 +0000185#define RGB_ALPHA 0
DRCb4570bb2011-09-07 06:31:00 +0000186#define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
187#define h2v1_merged_upsample_internal extxbgr_h2v1_merged_upsample_internal
188#define h2v2_merged_upsample_internal extxbgr_h2v2_merged_upsample_internal
189#include "jdmrgext.c"
190#undef RGB_RED
191#undef RGB_GREEN
192#undef RGB_BLUE
DRCcac10512012-03-16 14:37:36 +0000193#undef RGB_ALPHA
DRCb4570bb2011-09-07 06:31:00 +0000194#undef RGB_PIXELSIZE
195#undef h2v1_merged_upsample_internal
196#undef h2v2_merged_upsample_internal
197
198#define RGB_RED EXT_XRGB_RED
199#define RGB_GREEN EXT_XRGB_GREEN
200#define RGB_BLUE EXT_XRGB_BLUE
DRCcac10512012-03-16 14:37:36 +0000201#define RGB_ALPHA 0
DRCb4570bb2011-09-07 06:31:00 +0000202#define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
203#define h2v1_merged_upsample_internal extxrgb_h2v1_merged_upsample_internal
204#define h2v2_merged_upsample_internal extxrgb_h2v2_merged_upsample_internal
205#include "jdmrgext.c"
206#undef RGB_RED
207#undef RGB_GREEN
208#undef RGB_BLUE
DRCcac10512012-03-16 14:37:36 +0000209#undef RGB_ALPHA
DRCb4570bb2011-09-07 06:31:00 +0000210#undef RGB_PIXELSIZE
211#undef h2v1_merged_upsample_internal
212#undef h2v2_merged_upsample_internal
213
214
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000215/*
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000216 * Initialize tables for YCC->RGB colorspace conversion.
217 * This is taken directly from jdcolor.c; see that file for more info.
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000218 */
219
Thomas G. Lane489583f1996-02-07 00:00:00 +0000220LOCAL(void)
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000221build_ycc_rgb_table (j_decompress_ptr cinfo)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000222{
223 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000224 int i;
225 INT32 x;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000226 SHIFT_TEMPS
227
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000228 upsample->Cr_r_tab = (int *)
229 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DRC5de454b2014-05-18 19:04:03 +0000230 (MAXJSAMPLE+1) * sizeof(int));
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000231 upsample->Cb_b_tab = (int *)
232 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DRC5de454b2014-05-18 19:04:03 +0000233 (MAXJSAMPLE+1) * sizeof(int));
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000234 upsample->Cr_g_tab = (INT32 *)
235 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DRC5de454b2014-05-18 19:04:03 +0000236 (MAXJSAMPLE+1) * sizeof(INT32));
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000237 upsample->Cb_g_tab = (INT32 *)
238 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DRC5de454b2014-05-18 19:04:03 +0000239 (MAXJSAMPLE+1) * sizeof(INT32));
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000240
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +0000241 for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000242 /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +0000243 /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000244 /* Cr=>R value is nearest int to 1.40200 * x */
245 upsample->Cr_r_tab[i] = (int)
DRCe5eaf372014-05-09 18:00:32 +0000246 RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000247 /* Cb=>B value is nearest int to 1.77200 * x */
248 upsample->Cb_b_tab[i] = (int)
DRCe5eaf372014-05-09 18:00:32 +0000249 RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000250 /* Cr=>G value is scaled-up -0.71414 * x */
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +0000251 upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000252 /* Cb=>G value is scaled-up -0.34414 * x */
253 /* We also add in ONE_HALF so that need not do it in inner loop */
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +0000254 upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000255 }
256}
257
258
259/*
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000260 * Initialize for an upsampling pass.
261 */
262
Thomas G. Lane489583f1996-02-07 00:00:00 +0000263METHODDEF(void)
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000264start_pass_merged_upsample (j_decompress_ptr cinfo)
265{
266 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
267
268 /* Mark the spare buffer empty */
269 upsample->spare_full = FALSE;
270 /* Initialize total-height counter for detecting bottom of image */
271 upsample->rows_to_go = cinfo->output_height;
272}
273
274
275/*
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000276 * Control routine to do upsampling (and color conversion).
277 *
278 * The control routine just handles the row buffering considerations.
279 */
280
Thomas G. Lane489583f1996-02-07 00:00:00 +0000281METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000282merged_2v_upsample (j_decompress_ptr cinfo,
DRCe5eaf372014-05-09 18:00:32 +0000283 JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
284 JDIMENSION in_row_groups_avail,
285 JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
286 JDIMENSION out_rows_avail)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000287/* 2:1 vertical sampling case: may need a spare row. */
288{
289 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
290 JSAMPROW work_ptrs[2];
DRCe5eaf372014-05-09 18:00:32 +0000291 JDIMENSION num_rows; /* number of rows returned to caller */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000292
293 if (upsample->spare_full) {
294 /* If we have a spare row saved from a previous cycle, just return it. */
DRC78df2e62014-05-12 09:23:57 +0000295 JDIMENSION size = upsample->out_row_width;
296 if (cinfo->out_color_space == JCS_RGB565)
297 size = cinfo->output_width * 2;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000298 jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
DRC78df2e62014-05-12 09:23:57 +0000299 1, size);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000300 num_rows = 1;
301 upsample->spare_full = FALSE;
302 } else {
303 /* Figure number of rows to return to caller. */
304 num_rows = 2;
305 /* Not more than the distance to the end of the image. */
306 if (num_rows > upsample->rows_to_go)
307 num_rows = upsample->rows_to_go;
308 /* And not more than what the client can accept: */
309 out_rows_avail -= *out_row_ctr;
310 if (num_rows > out_rows_avail)
311 num_rows = out_rows_avail;
312 /* Create output pointer array for upsampler. */
313 work_ptrs[0] = output_buf[*out_row_ctr];
314 if (num_rows > 1) {
315 work_ptrs[1] = output_buf[*out_row_ctr + 1];
316 } else {
317 work_ptrs[1] = upsample->spare_row;
318 upsample->spare_full = TRUE;
319 }
320 /* Now do the upsampling. */
321 (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
322 }
323
324 /* Adjust counts */
325 *out_row_ctr += num_rows;
326 upsample->rows_to_go -= num_rows;
327 /* When the buffer is emptied, declare this input row group consumed */
328 if (! upsample->spare_full)
329 (*in_row_group_ctr)++;
330}
331
332
Thomas G. Lane489583f1996-02-07 00:00:00 +0000333METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000334merged_1v_upsample (j_decompress_ptr cinfo,
DRCe5eaf372014-05-09 18:00:32 +0000335 JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
336 JDIMENSION in_row_groups_avail,
337 JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
338 JDIMENSION out_rows_avail)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000339/* 1:1 vertical sampling case: much easier, never need a spare row. */
340{
341 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
342
343 /* Just do the upsampling. */
344 (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
DRCe5eaf372014-05-09 18:00:32 +0000345 output_buf + *out_row_ctr);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000346 /* Adjust counts */
347 (*out_row_ctr)++;
348 (*in_row_group_ctr)++;
349}
350
351
352/*
353 * These are the routines invoked by the control routines to do
354 * the actual upsampling/conversion. One row group is processed per call.
355 *
356 * Note: since we may be writing directly into application-supplied buffers,
357 * we have to be honest about the output width; we can't assume the buffer
358 * has been rounded up to an even width.
359 */
360
361
362/*
363 * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
364 */
365
Thomas G. Lane489583f1996-02-07 00:00:00 +0000366METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000367h2v1_merged_upsample (j_decompress_ptr cinfo,
DRCe5eaf372014-05-09 18:00:32 +0000368 JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
369 JSAMPARRAY output_buf)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000370{
DRCb4570bb2011-09-07 06:31:00 +0000371 switch (cinfo->out_color_space) {
372 case JCS_EXT_RGB:
373 extrgb_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
374 output_buf);
375 break;
376 case JCS_EXT_RGBX:
DRC67ce3b22011-12-19 02:21:03 +0000377 case JCS_EXT_RGBA:
DRCb4570bb2011-09-07 06:31:00 +0000378 extrgbx_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
379 output_buf);
380 break;
381 case JCS_EXT_BGR:
382 extbgr_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
383 output_buf);
384 break;
385 case JCS_EXT_BGRX:
DRC67ce3b22011-12-19 02:21:03 +0000386 case JCS_EXT_BGRA:
DRCb4570bb2011-09-07 06:31:00 +0000387 extbgrx_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
388 output_buf);
389 break;
390 case JCS_EXT_XBGR:
DRC67ce3b22011-12-19 02:21:03 +0000391 case JCS_EXT_ABGR:
DRCb4570bb2011-09-07 06:31:00 +0000392 extxbgr_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
393 output_buf);
394 break;
395 case JCS_EXT_XRGB:
DRC67ce3b22011-12-19 02:21:03 +0000396 case JCS_EXT_ARGB:
DRCb4570bb2011-09-07 06:31:00 +0000397 extxrgb_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
398 output_buf);
399 break;
400 default:
401 h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
402 output_buf);
403 break;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000404 }
405}
406
407
408/*
409 * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
410 */
411
Thomas G. Lane489583f1996-02-07 00:00:00 +0000412METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000413h2v2_merged_upsample (j_decompress_ptr cinfo,
DRCe5eaf372014-05-09 18:00:32 +0000414 JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
415 JSAMPARRAY output_buf)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000416{
DRCb4570bb2011-09-07 06:31:00 +0000417 switch (cinfo->out_color_space) {
418 case JCS_EXT_RGB:
419 extrgb_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
420 output_buf);
421 break;
422 case JCS_EXT_RGBX:
DRC67ce3b22011-12-19 02:21:03 +0000423 case JCS_EXT_RGBA:
DRCb4570bb2011-09-07 06:31:00 +0000424 extrgbx_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
425 output_buf);
426 break;
427 case JCS_EXT_BGR:
428 extbgr_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
429 output_buf);
430 break;
431 case JCS_EXT_BGRX:
DRC67ce3b22011-12-19 02:21:03 +0000432 case JCS_EXT_BGRA:
DRCb4570bb2011-09-07 06:31:00 +0000433 extbgrx_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
434 output_buf);
435 break;
436 case JCS_EXT_XBGR:
DRC67ce3b22011-12-19 02:21:03 +0000437 case JCS_EXT_ABGR:
DRCb4570bb2011-09-07 06:31:00 +0000438 extxbgr_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
439 output_buf);
440 break;
441 case JCS_EXT_XRGB:
DRC67ce3b22011-12-19 02:21:03 +0000442 case JCS_EXT_ARGB:
DRCb4570bb2011-09-07 06:31:00 +0000443 extxrgb_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
444 output_buf);
445 break;
446 default:
447 h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
448 output_buf);
449 break;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000450 }
451}
452
453
DRC78df2e62014-05-12 09:23:57 +0000454METHODDEF(void)
455h2v1_merged_upsample_565 (j_decompress_ptr cinfo,
456 JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
457 JSAMPARRAY output_buf)
458{
459 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
460 register int y, cred, cgreen, cblue;
461 int cb, cr;
462 register JSAMPROW outptr;
463 JSAMPROW inptr0, inptr1, inptr2;
464 JDIMENSION col;
465 /* copy these pointers into registers if possible */
466 register JSAMPLE * range_limit = cinfo->sample_range_limit;
467 int * Crrtab = upsample->Cr_r_tab;
468 int * Cbbtab = upsample->Cb_b_tab;
469 INT32 * Crgtab = upsample->Cr_g_tab;
470 INT32 * Cbgtab = upsample->Cb_g_tab;
471 unsigned int r, g, b;
472 INT32 rgb;
473 SHIFT_TEMPS
474
475 inptr0 = input_buf[0][in_row_group_ctr];
476 inptr1 = input_buf[1][in_row_group_ctr];
477 inptr2 = input_buf[2][in_row_group_ctr];
478 outptr = output_buf[0];
479
480 /* Loop for each pair of output pixels */
481 for (col = cinfo->output_width >> 1; col > 0; col--) {
482 /* Do the chroma part of the calculation */
483 cb = GETJSAMPLE(*inptr1++);
484 cr = GETJSAMPLE(*inptr2++);
485 cred = Crrtab[cr];
486 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
487 cblue = Cbbtab[cb];
488
489 /* Fetch 2 Y values and emit 2 pixels */
490 y = GETJSAMPLE(*inptr0++);
491 r = range_limit[y + cred];
492 g = range_limit[y + cgreen];
493 b = range_limit[y + cblue];
494 rgb = PACK_SHORT_565(r, g, b);
495
496 y = GETJSAMPLE(*inptr0++);
497 r = range_limit[y + cred];
498 g = range_limit[y + cgreen];
499 b = range_limit[y + cblue];
500 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
501
502 WRITE_TWO_PIXELS(outptr, rgb);
503 outptr += 4;
504 }
505
506 /* If image width is odd, do the last output column separately */
507 if (cinfo->output_width & 1) {
508 cb = GETJSAMPLE(*inptr1);
509 cr = GETJSAMPLE(*inptr2);
510 cred = Crrtab[cr];
511 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
512 cblue = Cbbtab[cb];
513 y = GETJSAMPLE(*inptr0);
514 r = range_limit[y + cred];
515 g = range_limit[y + cgreen];
516 b = range_limit[y + cblue];
517 rgb = PACK_SHORT_565(r, g, b);
518 *(INT16*)outptr = rgb;
519 }
520 }
521
522
523METHODDEF(void)
524h2v1_merged_upsample_565D (j_decompress_ptr cinfo,
525 JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
526 JSAMPARRAY output_buf)
527{
528 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
529 register int y, cred, cgreen, cblue;
530 int cb, cr;
531 register JSAMPROW outptr;
532 JSAMPROW inptr0, inptr1, inptr2;
533 JDIMENSION col;
534 /* copy these pointers into registers if possible */
535 register JSAMPLE * range_limit = cinfo->sample_range_limit;
536 int * Crrtab = upsample->Cr_r_tab;
537 int * Cbbtab = upsample->Cb_b_tab;
538 INT32 * Crgtab = upsample->Cr_g_tab;
539 INT32 * Cbgtab = upsample->Cb_g_tab;
540 INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
541 unsigned int r, g, b;
542 INT32 rgb;
543 SHIFT_TEMPS
544
545 inptr0 = input_buf[0][in_row_group_ctr];
546 inptr1 = input_buf[1][in_row_group_ctr];
547 inptr2 = input_buf[2][in_row_group_ctr];
548 outptr = output_buf[0];
549
550 /* Loop for each pair of output pixels */
551 for (col = cinfo->output_width >> 1; col > 0; col--) {
552 /* Do the chroma part of the calculation */
553 cb = GETJSAMPLE(*inptr1++);
554 cr = GETJSAMPLE(*inptr2++);
555 cred = Crrtab[cr];
556 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
557 cblue = Cbbtab[cb];
558
559 /* Fetch 2 Y values and emit 2 pixels */
560 y = GETJSAMPLE(*inptr0++);
561 r = range_limit[DITHER_565_R(y + cred, d0)];
562 g = range_limit[DITHER_565_G(y + cgreen, d0)];
563 b = range_limit[DITHER_565_B(y + cblue, d0)];
564 d0 = DITHER_ROTATE(d0);
565 rgb = PACK_SHORT_565(r, g, b);
566
567 y = GETJSAMPLE(*inptr0++);
568 r = range_limit[DITHER_565_R(y + cred, d0)];
569 g = range_limit[DITHER_565_G(y + cgreen, d0)];
570 b = range_limit[DITHER_565_B(y + cblue, d0)];
571 d0 = DITHER_ROTATE(d0);
572 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
573
574 WRITE_TWO_PIXELS(outptr, rgb);
575 outptr += 4;
576 }
577
578 /* If image width is odd, do the last output column separately */
579 if (cinfo->output_width & 1) {
580 cb = GETJSAMPLE(*inptr1);
581 cr = GETJSAMPLE(*inptr2);
582 cred = Crrtab[cr];
583 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
584 cblue = Cbbtab[cb];
585 y = GETJSAMPLE(*inptr0);
586 r = range_limit[DITHER_565_R(y + cred, d0)];
587 g = range_limit[DITHER_565_G(y + cgreen, d0)];
588 b = range_limit[DITHER_565_B(y + cblue, d0)];
589 rgb = PACK_SHORT_565(r, g, b);
590 *(INT16*)outptr = rgb;
591 }
592}
593
594
595METHODDEF(void)
596h2v2_merged_upsample_565 (j_decompress_ptr cinfo,
597 JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
598 JSAMPARRAY output_buf)
599{
600 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
601 register int y, cred, cgreen, cblue;
602 int cb, cr;
603 register JSAMPROW outptr0, outptr1;
604 JSAMPROW inptr00, inptr01, inptr1, inptr2;
605 JDIMENSION col;
606 /* copy these pointers into registers if possible */
607 register JSAMPLE * range_limit = cinfo->sample_range_limit;
608 int * Crrtab = upsample->Cr_r_tab;
609 int * Cbbtab = upsample->Cb_b_tab;
610 INT32 * Crgtab = upsample->Cr_g_tab;
611 INT32 * Cbgtab = upsample->Cb_g_tab;
612 unsigned int r, g, b;
613 INT32 rgb;
614 SHIFT_TEMPS
615
616 inptr00 = input_buf[0][in_row_group_ctr * 2];
617 inptr01 = input_buf[0][in_row_group_ctr * 2 + 1];
618 inptr1 = input_buf[1][in_row_group_ctr];
619 inptr2 = input_buf[2][in_row_group_ctr];
620 outptr0 = output_buf[0];
621 outptr1 = output_buf[1];
622
623 /* Loop for each group of output pixels */
624 for (col = cinfo->output_width >> 1; col > 0; col--) {
625 /* Do the chroma part of the calculation */
626 cb = GETJSAMPLE(*inptr1++);
627 cr = GETJSAMPLE(*inptr2++);
628 cred = Crrtab[cr];
629 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
630 cblue = Cbbtab[cb];
631
632 /* Fetch 4 Y values and emit 4 pixels */
633 y = GETJSAMPLE(*inptr00++);
634 r = range_limit[y + cred];
635 g = range_limit[y + cgreen];
636 b = range_limit[y + cblue];
637 rgb = PACK_SHORT_565(r, g, b);
638
639 y = GETJSAMPLE(*inptr00++);
640 r = range_limit[y + cred];
641 g = range_limit[y + cgreen];
642 b = range_limit[y + cblue];
643 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
644
645 WRITE_TWO_PIXELS(outptr0, rgb);
646 outptr0 += 4;
647
648 y = GETJSAMPLE(*inptr01++);
649 r = range_limit[y + cred];
650 g = range_limit[y + cgreen];
651 b = range_limit[y + cblue];
652 rgb = PACK_SHORT_565(r, g, b);
653
654 y = GETJSAMPLE(*inptr01++);
655 r = range_limit[y + cred];
656 g = range_limit[y + cgreen];
657 b = range_limit[y + cblue];
658 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
659
660 WRITE_TWO_PIXELS(outptr1, rgb);
661 outptr1 += 4;
662 }
663
664 /* If image width is odd, do the last output column separately */
665 if (cinfo->output_width & 1) {
666 cb = GETJSAMPLE(*inptr1);
667 cr = GETJSAMPLE(*inptr2);
668 cred = Crrtab[cr];
669 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
670 cblue = Cbbtab[cb];
671
672 y = GETJSAMPLE(*inptr00);
673 r = range_limit[y + cred];
674 g = range_limit[y + cgreen];
675 b = range_limit[y + cblue];
676 rgb = PACK_SHORT_565(r, g, b);
677 *(INT16*)outptr0 = rgb;
678
679 y = GETJSAMPLE(*inptr01);
680 r = range_limit[y + cred];
681 g = range_limit[y + cgreen];
682 b = range_limit[y + cblue];
683 rgb = PACK_SHORT_565(r, g, b);
684 *(INT16*)outptr1 = rgb;
685 }
686}
687
688
689METHODDEF(void)
690h2v2_merged_upsample_565D (j_decompress_ptr cinfo,
691 JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
692 JSAMPARRAY output_buf)
693{
694 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
695 register int y, cred, cgreen, cblue;
696 int cb, cr;
697 register JSAMPROW outptr0, outptr1;
698 JSAMPROW inptr00, inptr01, inptr1, inptr2;
699 JDIMENSION col;
700 /* copy these pointers into registers if possible */
701 register JSAMPLE * range_limit = cinfo->sample_range_limit;
702 int * Crrtab = upsample->Cr_r_tab;
703 int * Cbbtab = upsample->Cb_b_tab;
704 INT32 * Crgtab = upsample->Cr_g_tab;
705 INT32 * Cbgtab = upsample->Cb_g_tab;
706 INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
707 INT32 d1 = dither_matrix[(cinfo->output_scanline+1) & DITHER_MASK];
708 unsigned int r, g, b;
709 INT32 rgb;
710 SHIFT_TEMPS
711
712 inptr00 = input_buf[0][in_row_group_ctr*2];
713 inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
714 inptr1 = input_buf[1][in_row_group_ctr];
715 inptr2 = input_buf[2][in_row_group_ctr];
716 outptr0 = output_buf[0];
717 outptr1 = output_buf[1];
718
719 /* Loop for each group of output pixels */
720 for (col = cinfo->output_width >> 1; col > 0; col--) {
721 /* Do the chroma part of the calculation */
722 cb = GETJSAMPLE(*inptr1++);
723 cr = GETJSAMPLE(*inptr2++);
724 cred = Crrtab[cr];
725 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
726 cblue = Cbbtab[cb];
727
728 /* Fetch 4 Y values and emit 4 pixels */
729 y = GETJSAMPLE(*inptr00++);
730 r = range_limit[DITHER_565_R(y + cred, d0)];
731 g = range_limit[DITHER_565_G(y + cgreen, d0)];
732 b = range_limit[DITHER_565_B(y + cblue, d0)];
733 d0 = DITHER_ROTATE(d0);
734 rgb = PACK_SHORT_565(r, g, b);
735
736 y = GETJSAMPLE(*inptr00++);
737 r = range_limit[DITHER_565_R(y + cred, d1)];
738 g = range_limit[DITHER_565_G(y + cgreen, d1)];
739 b = range_limit[DITHER_565_B(y + cblue, d1)];
740 d1 = DITHER_ROTATE(d1);
741 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
742
743 WRITE_TWO_PIXELS(outptr0, rgb);
744 outptr0 += 4;
745
746 y = GETJSAMPLE(*inptr01++);
747 r = range_limit[DITHER_565_R(y + cred, d0)];
748 g = range_limit[DITHER_565_G(y + cgreen, d0)];
749 b = range_limit[DITHER_565_B(y + cblue, d0)];
750 d0 = DITHER_ROTATE(d0);
751 rgb = PACK_SHORT_565(r, g, b);
752
753 y = GETJSAMPLE(*inptr01++);
754 r = range_limit[DITHER_565_R(y + cred, d1)];
755 g = range_limit[DITHER_565_G(y + cgreen, d1)];
756 b = range_limit[DITHER_565_B(y + cblue, d1)];
757 d1 = DITHER_ROTATE(d1);
758 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
759
760 WRITE_TWO_PIXELS(outptr1, rgb);
761 outptr1 += 4;
762 }
763
764 /* If image width is odd, do the last output column separately */
765 if (cinfo->output_width & 1) {
766 cb = GETJSAMPLE(*inptr1);
767 cr = GETJSAMPLE(*inptr2);
768 cred = Crrtab[cr];
769 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
770 cblue = Cbbtab[cb];
771
772 y = GETJSAMPLE(*inptr00);
773 r = range_limit[DITHER_565_R(y + cred, d0)];
774 g = range_limit[DITHER_565_G(y + cgreen, d0)];
775 b = range_limit[DITHER_565_B(y + cblue, d0)];
776 rgb = PACK_SHORT_565(r, g, b);
777 *(INT16*)outptr0 = rgb;
778
779 y = GETJSAMPLE(*inptr01);
780 r = range_limit[DITHER_565_R(y + cred, d1)];
781 g = range_limit[DITHER_565_G(y + cgreen, d1)];
782 b = range_limit[DITHER_565_B(y + cblue, d1)];
783 rgb = PACK_SHORT_565(r, g, b);
784 *(INT16*)outptr1 = rgb;
785 }
786}
787
788
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000789/*
790 * Module initialization routine for merged upsampling/color conversion.
791 *
792 * NB: this is called under the conditions determined by use_merged_upsample()
793 * in jdmaster.c. That routine MUST correspond to the actual capabilities
794 * of this module; no safety checks are made here.
795 */
796
Thomas G. Lane489583f1996-02-07 00:00:00 +0000797GLOBAL(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000798jinit_merged_upsampler (j_decompress_ptr cinfo)
799{
800 my_upsample_ptr upsample;
801
802 upsample = (my_upsample_ptr)
803 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DRC5de454b2014-05-18 19:04:03 +0000804 sizeof(my_upsampler));
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000805 cinfo->upsample = (struct jpeg_upsampler *) upsample;
806 upsample->pub.start_pass = start_pass_merged_upsample;
807 upsample->pub.need_context_rows = FALSE;
808
809 upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
810
811 if (cinfo->max_v_samp_factor == 2) {
812 upsample->pub.upsample = merged_2v_upsample;
Pierre Ossman59a39382009-03-09 13:15:56 +0000813 if (jsimd_can_h2v2_merged_upsample())
814 upsample->upmethod = jsimd_h2v2_merged_upsample;
815 else
816 upsample->upmethod = h2v2_merged_upsample;
DRC78df2e62014-05-12 09:23:57 +0000817 if (cinfo->out_color_space == JCS_RGB565) {
818 if (cinfo->dither_mode != JDITHER_NONE) {
819 upsample->upmethod = h2v2_merged_upsample_565D;
820 } else {
821 upsample->upmethod = h2v2_merged_upsample_565;
822 }
823 }
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000824 /* Allocate a spare row buffer */
825 upsample->spare_row = (JSAMPROW)
826 (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DRC5de454b2014-05-18 19:04:03 +0000827 (size_t) (upsample->out_row_width * sizeof(JSAMPLE)));
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000828 } else {
829 upsample->pub.upsample = merged_1v_upsample;
Pierre Ossman59a39382009-03-09 13:15:56 +0000830 if (jsimd_can_h2v1_merged_upsample())
831 upsample->upmethod = jsimd_h2v1_merged_upsample;
832 else
833 upsample->upmethod = h2v1_merged_upsample;
DRC78df2e62014-05-12 09:23:57 +0000834 if (cinfo->out_color_space == JCS_RGB565) {
835 if (cinfo->dither_mode != JDITHER_NONE) {
836 upsample->upmethod = h2v1_merged_upsample_565D;
837 } else {
838 upsample->upmethod = h2v1_merged_upsample_565;
839 }
840 }
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000841 /* No spare row needed */
842 upsample->spare_row = NULL;
843 }
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000844
845 build_ycc_rgb_table(cinfo);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000846}
847
848#endif /* UPSAMPLE_MERGING_SUPPORTED */