blob: b82fe4747edad6eaa1832d0b097618159fd63574 [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 */
86 JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
DRCe5eaf372014-05-09 18:00:32 +000087 JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
88 JSAMPARRAY output_buf));
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000089
90 /* Private state for YCC->RGB conversion */
DRCe5eaf372014-05-09 18:00:32 +000091 int * Cr_r_tab; /* => table for Cr to R conversion */
92 int * Cb_b_tab; /* => table for Cb to B conversion */
93 INT32 * Cr_g_tab; /* => table for Cr to G conversion */
94 INT32 * Cb_g_tab; /* => table for Cb to G conversion */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000095
96 /* For 2:1 vertical sampling, we produce two output rows at a time.
97 * We need a "spare" row buffer to hold the second output row if the
98 * application provides just a one-row buffer; we also use the spare
99 * to discard the dummy last row if the image height is odd.
100 */
101 JSAMPROW spare_row;
DRCe5eaf372014-05-09 18:00:32 +0000102 boolean spare_full; /* T if spare buffer is occupied */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000103
DRCe5eaf372014-05-09 18:00:32 +0000104 JDIMENSION out_row_width; /* samples per output row */
105 JDIMENSION rows_to_go; /* counts rows remaining in image */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000106} my_upsampler;
107
108typedef my_upsampler * my_upsample_ptr;
109
DRCe5eaf372014-05-09 18:00:32 +0000110#define SCALEBITS 16 /* speediest right-shift on some machines */
111#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
112#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000113
114
DRCb4570bb2011-09-07 06:31:00 +0000115/* Include inline routines for colorspace extensions */
116
117#include "jdmrgext.c"
118#undef RGB_RED
119#undef RGB_GREEN
120#undef RGB_BLUE
121#undef RGB_PIXELSIZE
122
123#define RGB_RED EXT_RGB_RED
124#define RGB_GREEN EXT_RGB_GREEN
125#define RGB_BLUE EXT_RGB_BLUE
126#define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
127#define h2v1_merged_upsample_internal extrgb_h2v1_merged_upsample_internal
128#define h2v2_merged_upsample_internal extrgb_h2v2_merged_upsample_internal
129#include "jdmrgext.c"
130#undef RGB_RED
131#undef RGB_GREEN
132#undef RGB_BLUE
133#undef RGB_PIXELSIZE
134#undef h2v1_merged_upsample_internal
135#undef h2v2_merged_upsample_internal
136
137#define RGB_RED EXT_RGBX_RED
138#define RGB_GREEN EXT_RGBX_GREEN
139#define RGB_BLUE EXT_RGBX_BLUE
DRCcac10512012-03-16 14:37:36 +0000140#define RGB_ALPHA 3
DRCb4570bb2011-09-07 06:31:00 +0000141#define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
142#define h2v1_merged_upsample_internal extrgbx_h2v1_merged_upsample_internal
143#define h2v2_merged_upsample_internal extrgbx_h2v2_merged_upsample_internal
144#include "jdmrgext.c"
145#undef RGB_RED
146#undef RGB_GREEN
147#undef RGB_BLUE
DRCcac10512012-03-16 14:37:36 +0000148#undef RGB_ALPHA
DRCb4570bb2011-09-07 06:31:00 +0000149#undef RGB_PIXELSIZE
150#undef h2v1_merged_upsample_internal
151#undef h2v2_merged_upsample_internal
152
153#define RGB_RED EXT_BGR_RED
154#define RGB_GREEN EXT_BGR_GREEN
155#define RGB_BLUE EXT_BGR_BLUE
156#define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
157#define h2v1_merged_upsample_internal extbgr_h2v1_merged_upsample_internal
158#define h2v2_merged_upsample_internal extbgr_h2v2_merged_upsample_internal
159#include "jdmrgext.c"
160#undef RGB_RED
161#undef RGB_GREEN
162#undef RGB_BLUE
163#undef RGB_PIXELSIZE
164#undef h2v1_merged_upsample_internal
165#undef h2v2_merged_upsample_internal
166
167#define RGB_RED EXT_BGRX_RED
168#define RGB_GREEN EXT_BGRX_GREEN
169#define RGB_BLUE EXT_BGRX_BLUE
DRCcac10512012-03-16 14:37:36 +0000170#define RGB_ALPHA 3
DRCb4570bb2011-09-07 06:31:00 +0000171#define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
172#define h2v1_merged_upsample_internal extbgrx_h2v1_merged_upsample_internal
173#define h2v2_merged_upsample_internal extbgrx_h2v2_merged_upsample_internal
174#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#define RGB_RED EXT_XBGR_RED
184#define RGB_GREEN EXT_XBGR_GREEN
185#define RGB_BLUE EXT_XBGR_BLUE
DRCcac10512012-03-16 14:37:36 +0000186#define RGB_ALPHA 0
DRCb4570bb2011-09-07 06:31:00 +0000187#define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
188#define h2v1_merged_upsample_internal extxbgr_h2v1_merged_upsample_internal
189#define h2v2_merged_upsample_internal extxbgr_h2v2_merged_upsample_internal
190#include "jdmrgext.c"
191#undef RGB_RED
192#undef RGB_GREEN
193#undef RGB_BLUE
DRCcac10512012-03-16 14:37:36 +0000194#undef RGB_ALPHA
DRCb4570bb2011-09-07 06:31:00 +0000195#undef RGB_PIXELSIZE
196#undef h2v1_merged_upsample_internal
197#undef h2v2_merged_upsample_internal
198
199#define RGB_RED EXT_XRGB_RED
200#define RGB_GREEN EXT_XRGB_GREEN
201#define RGB_BLUE EXT_XRGB_BLUE
DRCcac10512012-03-16 14:37:36 +0000202#define RGB_ALPHA 0
DRCb4570bb2011-09-07 06:31:00 +0000203#define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
204#define h2v1_merged_upsample_internal extxrgb_h2v1_merged_upsample_internal
205#define h2v2_merged_upsample_internal extxrgb_h2v2_merged_upsample_internal
206#include "jdmrgext.c"
207#undef RGB_RED
208#undef RGB_GREEN
209#undef RGB_BLUE
DRCcac10512012-03-16 14:37:36 +0000210#undef RGB_ALPHA
DRCb4570bb2011-09-07 06:31:00 +0000211#undef RGB_PIXELSIZE
212#undef h2v1_merged_upsample_internal
213#undef h2v2_merged_upsample_internal
214
215
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000216/*
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000217 * Initialize tables for YCC->RGB colorspace conversion.
218 * This is taken directly from jdcolor.c; see that file for more info.
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000219 */
220
Thomas G. Lane489583f1996-02-07 00:00:00 +0000221LOCAL(void)
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000222build_ycc_rgb_table (j_decompress_ptr cinfo)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000223{
224 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000225 int i;
226 INT32 x;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000227 SHIFT_TEMPS
228
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000229 upsample->Cr_r_tab = (int *)
230 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DRCe5eaf372014-05-09 18:00:32 +0000231 (MAXJSAMPLE+1) * SIZEOF(int));
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000232 upsample->Cb_b_tab = (int *)
233 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DRCe5eaf372014-05-09 18:00:32 +0000234 (MAXJSAMPLE+1) * SIZEOF(int));
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000235 upsample->Cr_g_tab = (INT32 *)
236 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DRCe5eaf372014-05-09 18:00:32 +0000237 (MAXJSAMPLE+1) * SIZEOF(INT32));
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000238 upsample->Cb_g_tab = (INT32 *)
239 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DRCe5eaf372014-05-09 18:00:32 +0000240 (MAXJSAMPLE+1) * SIZEOF(INT32));
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000241
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +0000242 for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000243 /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +0000244 /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000245 /* Cr=>R value is nearest int to 1.40200 * x */
246 upsample->Cr_r_tab[i] = (int)
DRCe5eaf372014-05-09 18:00:32 +0000247 RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000248 /* Cb=>B value is nearest int to 1.77200 * x */
249 upsample->Cb_b_tab[i] = (int)
DRCe5eaf372014-05-09 18:00:32 +0000250 RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000251 /* Cr=>G value is scaled-up -0.71414 * x */
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +0000252 upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000253 /* Cb=>G value is scaled-up -0.34414 * x */
254 /* We also add in ONE_HALF so that need not do it in inner loop */
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +0000255 upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000256 }
257}
258
259
260/*
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000261 * Initialize for an upsampling pass.
262 */
263
Thomas G. Lane489583f1996-02-07 00:00:00 +0000264METHODDEF(void)
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000265start_pass_merged_upsample (j_decompress_ptr cinfo)
266{
267 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
268
269 /* Mark the spare buffer empty */
270 upsample->spare_full = FALSE;
271 /* Initialize total-height counter for detecting bottom of image */
272 upsample->rows_to_go = cinfo->output_height;
273}
274
275
276/*
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000277 * Control routine to do upsampling (and color conversion).
278 *
279 * The control routine just handles the row buffering considerations.
280 */
281
Thomas G. Lane489583f1996-02-07 00:00:00 +0000282METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000283merged_2v_upsample (j_decompress_ptr cinfo,
DRCe5eaf372014-05-09 18:00:32 +0000284 JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
285 JDIMENSION in_row_groups_avail,
286 JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
287 JDIMENSION out_rows_avail)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000288/* 2:1 vertical sampling case: may need a spare row. */
289{
290 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
291 JSAMPROW work_ptrs[2];
DRCe5eaf372014-05-09 18:00:32 +0000292 JDIMENSION num_rows; /* number of rows returned to caller */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000293
294 if (upsample->spare_full) {
295 /* If we have a spare row saved from a previous cycle, just return it. */
DRC78df2e62014-05-12 09:23:57 +0000296 JDIMENSION size = upsample->out_row_width;
297 if (cinfo->out_color_space == JCS_RGB565)
298 size = cinfo->output_width * 2;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000299 jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
DRC78df2e62014-05-12 09:23:57 +0000300 1, size);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000301 num_rows = 1;
302 upsample->spare_full = FALSE;
303 } else {
304 /* Figure number of rows to return to caller. */
305 num_rows = 2;
306 /* Not more than the distance to the end of the image. */
307 if (num_rows > upsample->rows_to_go)
308 num_rows = upsample->rows_to_go;
309 /* And not more than what the client can accept: */
310 out_rows_avail -= *out_row_ctr;
311 if (num_rows > out_rows_avail)
312 num_rows = out_rows_avail;
313 /* Create output pointer array for upsampler. */
314 work_ptrs[0] = output_buf[*out_row_ctr];
315 if (num_rows > 1) {
316 work_ptrs[1] = output_buf[*out_row_ctr + 1];
317 } else {
318 work_ptrs[1] = upsample->spare_row;
319 upsample->spare_full = TRUE;
320 }
321 /* Now do the upsampling. */
322 (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
323 }
324
325 /* Adjust counts */
326 *out_row_ctr += num_rows;
327 upsample->rows_to_go -= num_rows;
328 /* When the buffer is emptied, declare this input row group consumed */
329 if (! upsample->spare_full)
330 (*in_row_group_ctr)++;
331}
332
333
Thomas G. Lane489583f1996-02-07 00:00:00 +0000334METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000335merged_1v_upsample (j_decompress_ptr cinfo,
DRCe5eaf372014-05-09 18:00:32 +0000336 JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
337 JDIMENSION in_row_groups_avail,
338 JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
339 JDIMENSION out_rows_avail)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000340/* 1:1 vertical sampling case: much easier, never need a spare row. */
341{
342 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
343
344 /* Just do the upsampling. */
345 (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
DRCe5eaf372014-05-09 18:00:32 +0000346 output_buf + *out_row_ctr);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000347 /* Adjust counts */
348 (*out_row_ctr)++;
349 (*in_row_group_ctr)++;
350}
351
352
353/*
354 * These are the routines invoked by the control routines to do
355 * the actual upsampling/conversion. One row group is processed per call.
356 *
357 * Note: since we may be writing directly into application-supplied buffers,
358 * we have to be honest about the output width; we can't assume the buffer
359 * has been rounded up to an even width.
360 */
361
362
363/*
364 * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
365 */
366
Thomas G. Lane489583f1996-02-07 00:00:00 +0000367METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000368h2v1_merged_upsample (j_decompress_ptr cinfo,
DRCe5eaf372014-05-09 18:00:32 +0000369 JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
370 JSAMPARRAY output_buf)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000371{
DRCb4570bb2011-09-07 06:31:00 +0000372 switch (cinfo->out_color_space) {
373 case JCS_EXT_RGB:
374 extrgb_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
375 output_buf);
376 break;
377 case JCS_EXT_RGBX:
DRC67ce3b22011-12-19 02:21:03 +0000378 case JCS_EXT_RGBA:
DRCb4570bb2011-09-07 06:31:00 +0000379 extrgbx_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
380 output_buf);
381 break;
382 case JCS_EXT_BGR:
383 extbgr_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
384 output_buf);
385 break;
386 case JCS_EXT_BGRX:
DRC67ce3b22011-12-19 02:21:03 +0000387 case JCS_EXT_BGRA:
DRCb4570bb2011-09-07 06:31:00 +0000388 extbgrx_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
389 output_buf);
390 break;
391 case JCS_EXT_XBGR:
DRC67ce3b22011-12-19 02:21:03 +0000392 case JCS_EXT_ABGR:
DRCb4570bb2011-09-07 06:31:00 +0000393 extxbgr_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
394 output_buf);
395 break;
396 case JCS_EXT_XRGB:
DRC67ce3b22011-12-19 02:21:03 +0000397 case JCS_EXT_ARGB:
DRCb4570bb2011-09-07 06:31:00 +0000398 extxrgb_h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
399 output_buf);
400 break;
401 default:
402 h2v1_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
403 output_buf);
404 break;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000405 }
406}
407
408
409/*
410 * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
411 */
412
Thomas G. Lane489583f1996-02-07 00:00:00 +0000413METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000414h2v2_merged_upsample (j_decompress_ptr cinfo,
DRCe5eaf372014-05-09 18:00:32 +0000415 JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
416 JSAMPARRAY output_buf)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000417{
DRCb4570bb2011-09-07 06:31:00 +0000418 switch (cinfo->out_color_space) {
419 case JCS_EXT_RGB:
420 extrgb_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
421 output_buf);
422 break;
423 case JCS_EXT_RGBX:
DRC67ce3b22011-12-19 02:21:03 +0000424 case JCS_EXT_RGBA:
DRCb4570bb2011-09-07 06:31:00 +0000425 extrgbx_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
426 output_buf);
427 break;
428 case JCS_EXT_BGR:
429 extbgr_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
430 output_buf);
431 break;
432 case JCS_EXT_BGRX:
DRC67ce3b22011-12-19 02:21:03 +0000433 case JCS_EXT_BGRA:
DRCb4570bb2011-09-07 06:31:00 +0000434 extbgrx_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
435 output_buf);
436 break;
437 case JCS_EXT_XBGR:
DRC67ce3b22011-12-19 02:21:03 +0000438 case JCS_EXT_ABGR:
DRCb4570bb2011-09-07 06:31:00 +0000439 extxbgr_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
440 output_buf);
441 break;
442 case JCS_EXT_XRGB:
DRC67ce3b22011-12-19 02:21:03 +0000443 case JCS_EXT_ARGB:
DRCb4570bb2011-09-07 06:31:00 +0000444 extxrgb_h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
445 output_buf);
446 break;
447 default:
448 h2v2_merged_upsample_internal(cinfo, input_buf, in_row_group_ctr,
449 output_buf);
450 break;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000451 }
452}
453
454
DRC78df2e62014-05-12 09:23:57 +0000455METHODDEF(void)
456h2v1_merged_upsample_565 (j_decompress_ptr cinfo,
457 JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
458 JSAMPARRAY output_buf)
459{
460 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
461 register int y, cred, cgreen, cblue;
462 int cb, cr;
463 register JSAMPROW outptr;
464 JSAMPROW inptr0, inptr1, inptr2;
465 JDIMENSION col;
466 /* copy these pointers into registers if possible */
467 register JSAMPLE * range_limit = cinfo->sample_range_limit;
468 int * Crrtab = upsample->Cr_r_tab;
469 int * Cbbtab = upsample->Cb_b_tab;
470 INT32 * Crgtab = upsample->Cr_g_tab;
471 INT32 * Cbgtab = upsample->Cb_g_tab;
472 unsigned int r, g, b;
473 INT32 rgb;
474 SHIFT_TEMPS
475
476 inptr0 = input_buf[0][in_row_group_ctr];
477 inptr1 = input_buf[1][in_row_group_ctr];
478 inptr2 = input_buf[2][in_row_group_ctr];
479 outptr = output_buf[0];
480
481 /* Loop for each pair of output pixels */
482 for (col = cinfo->output_width >> 1; col > 0; col--) {
483 /* Do the chroma part of the calculation */
484 cb = GETJSAMPLE(*inptr1++);
485 cr = GETJSAMPLE(*inptr2++);
486 cred = Crrtab[cr];
487 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
488 cblue = Cbbtab[cb];
489
490 /* Fetch 2 Y values and emit 2 pixels */
491 y = GETJSAMPLE(*inptr0++);
492 r = range_limit[y + cred];
493 g = range_limit[y + cgreen];
494 b = range_limit[y + cblue];
495 rgb = PACK_SHORT_565(r, g, b);
496
497 y = GETJSAMPLE(*inptr0++);
498 r = range_limit[y + cred];
499 g = range_limit[y + cgreen];
500 b = range_limit[y + cblue];
501 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
502
503 WRITE_TWO_PIXELS(outptr, rgb);
504 outptr += 4;
505 }
506
507 /* If image width is odd, do the last output column separately */
508 if (cinfo->output_width & 1) {
509 cb = GETJSAMPLE(*inptr1);
510 cr = GETJSAMPLE(*inptr2);
511 cred = Crrtab[cr];
512 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
513 cblue = Cbbtab[cb];
514 y = GETJSAMPLE(*inptr0);
515 r = range_limit[y + cred];
516 g = range_limit[y + cgreen];
517 b = range_limit[y + cblue];
518 rgb = PACK_SHORT_565(r, g, b);
519 *(INT16*)outptr = rgb;
520 }
521 }
522
523
524METHODDEF(void)
525h2v1_merged_upsample_565D (j_decompress_ptr cinfo,
526 JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
527 JSAMPARRAY output_buf)
528{
529 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
530 register int y, cred, cgreen, cblue;
531 int cb, cr;
532 register JSAMPROW outptr;
533 JSAMPROW inptr0, inptr1, inptr2;
534 JDIMENSION col;
535 /* copy these pointers into registers if possible */
536 register JSAMPLE * range_limit = cinfo->sample_range_limit;
537 int * Crrtab = upsample->Cr_r_tab;
538 int * Cbbtab = upsample->Cb_b_tab;
539 INT32 * Crgtab = upsample->Cr_g_tab;
540 INT32 * Cbgtab = upsample->Cb_g_tab;
541 INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
542 unsigned int r, g, b;
543 INT32 rgb;
544 SHIFT_TEMPS
545
546 inptr0 = input_buf[0][in_row_group_ctr];
547 inptr1 = input_buf[1][in_row_group_ctr];
548 inptr2 = input_buf[2][in_row_group_ctr];
549 outptr = output_buf[0];
550
551 /* Loop for each pair of output pixels */
552 for (col = cinfo->output_width >> 1; col > 0; col--) {
553 /* Do the chroma part of the calculation */
554 cb = GETJSAMPLE(*inptr1++);
555 cr = GETJSAMPLE(*inptr2++);
556 cred = Crrtab[cr];
557 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
558 cblue = Cbbtab[cb];
559
560 /* Fetch 2 Y values and emit 2 pixels */
561 y = GETJSAMPLE(*inptr0++);
562 r = range_limit[DITHER_565_R(y + cred, d0)];
563 g = range_limit[DITHER_565_G(y + cgreen, d0)];
564 b = range_limit[DITHER_565_B(y + cblue, d0)];
565 d0 = DITHER_ROTATE(d0);
566 rgb = PACK_SHORT_565(r, g, b);
567
568 y = GETJSAMPLE(*inptr0++);
569 r = range_limit[DITHER_565_R(y + cred, d0)];
570 g = range_limit[DITHER_565_G(y + cgreen, d0)];
571 b = range_limit[DITHER_565_B(y + cblue, d0)];
572 d0 = DITHER_ROTATE(d0);
573 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
574
575 WRITE_TWO_PIXELS(outptr, rgb);
576 outptr += 4;
577 }
578
579 /* If image width is odd, do the last output column separately */
580 if (cinfo->output_width & 1) {
581 cb = GETJSAMPLE(*inptr1);
582 cr = GETJSAMPLE(*inptr2);
583 cred = Crrtab[cr];
584 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
585 cblue = Cbbtab[cb];
586 y = GETJSAMPLE(*inptr0);
587 r = range_limit[DITHER_565_R(y + cred, d0)];
588 g = range_limit[DITHER_565_G(y + cgreen, d0)];
589 b = range_limit[DITHER_565_B(y + cblue, d0)];
590 rgb = PACK_SHORT_565(r, g, b);
591 *(INT16*)outptr = rgb;
592 }
593}
594
595
596METHODDEF(void)
597h2v2_merged_upsample_565 (j_decompress_ptr cinfo,
598 JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
599 JSAMPARRAY output_buf)
600{
601 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
602 register int y, cred, cgreen, cblue;
603 int cb, cr;
604 register JSAMPROW outptr0, outptr1;
605 JSAMPROW inptr00, inptr01, inptr1, inptr2;
606 JDIMENSION col;
607 /* copy these pointers into registers if possible */
608 register JSAMPLE * range_limit = cinfo->sample_range_limit;
609 int * Crrtab = upsample->Cr_r_tab;
610 int * Cbbtab = upsample->Cb_b_tab;
611 INT32 * Crgtab = upsample->Cr_g_tab;
612 INT32 * Cbgtab = upsample->Cb_g_tab;
613 unsigned int r, g, b;
614 INT32 rgb;
615 SHIFT_TEMPS
616
617 inptr00 = input_buf[0][in_row_group_ctr * 2];
618 inptr01 = input_buf[0][in_row_group_ctr * 2 + 1];
619 inptr1 = input_buf[1][in_row_group_ctr];
620 inptr2 = input_buf[2][in_row_group_ctr];
621 outptr0 = output_buf[0];
622 outptr1 = output_buf[1];
623
624 /* Loop for each group of output pixels */
625 for (col = cinfo->output_width >> 1; col > 0; col--) {
626 /* Do the chroma part of the calculation */
627 cb = GETJSAMPLE(*inptr1++);
628 cr = GETJSAMPLE(*inptr2++);
629 cred = Crrtab[cr];
630 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
631 cblue = Cbbtab[cb];
632
633 /* Fetch 4 Y values and emit 4 pixels */
634 y = GETJSAMPLE(*inptr00++);
635 r = range_limit[y + cred];
636 g = range_limit[y + cgreen];
637 b = range_limit[y + cblue];
638 rgb = PACK_SHORT_565(r, g, b);
639
640 y = GETJSAMPLE(*inptr00++);
641 r = range_limit[y + cred];
642 g = range_limit[y + cgreen];
643 b = range_limit[y + cblue];
644 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
645
646 WRITE_TWO_PIXELS(outptr0, rgb);
647 outptr0 += 4;
648
649 y = GETJSAMPLE(*inptr01++);
650 r = range_limit[y + cred];
651 g = range_limit[y + cgreen];
652 b = range_limit[y + cblue];
653 rgb = PACK_SHORT_565(r, g, b);
654
655 y = GETJSAMPLE(*inptr01++);
656 r = range_limit[y + cred];
657 g = range_limit[y + cgreen];
658 b = range_limit[y + cblue];
659 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
660
661 WRITE_TWO_PIXELS(outptr1, rgb);
662 outptr1 += 4;
663 }
664
665 /* If image width is odd, do the last output column separately */
666 if (cinfo->output_width & 1) {
667 cb = GETJSAMPLE(*inptr1);
668 cr = GETJSAMPLE(*inptr2);
669 cred = Crrtab[cr];
670 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
671 cblue = Cbbtab[cb];
672
673 y = GETJSAMPLE(*inptr00);
674 r = range_limit[y + cred];
675 g = range_limit[y + cgreen];
676 b = range_limit[y + cblue];
677 rgb = PACK_SHORT_565(r, g, b);
678 *(INT16*)outptr0 = rgb;
679
680 y = GETJSAMPLE(*inptr01);
681 r = range_limit[y + cred];
682 g = range_limit[y + cgreen];
683 b = range_limit[y + cblue];
684 rgb = PACK_SHORT_565(r, g, b);
685 *(INT16*)outptr1 = rgb;
686 }
687}
688
689
690METHODDEF(void)
691h2v2_merged_upsample_565D (j_decompress_ptr cinfo,
692 JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
693 JSAMPARRAY output_buf)
694{
695 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
696 register int y, cred, cgreen, cblue;
697 int cb, cr;
698 register JSAMPROW outptr0, outptr1;
699 JSAMPROW inptr00, inptr01, inptr1, inptr2;
700 JDIMENSION col;
701 /* copy these pointers into registers if possible */
702 register JSAMPLE * range_limit = cinfo->sample_range_limit;
703 int * Crrtab = upsample->Cr_r_tab;
704 int * Cbbtab = upsample->Cb_b_tab;
705 INT32 * Crgtab = upsample->Cr_g_tab;
706 INT32 * Cbgtab = upsample->Cb_g_tab;
707 INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
708 INT32 d1 = dither_matrix[(cinfo->output_scanline+1) & DITHER_MASK];
709 unsigned int r, g, b;
710 INT32 rgb;
711 SHIFT_TEMPS
712
713 inptr00 = input_buf[0][in_row_group_ctr*2];
714 inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
715 inptr1 = input_buf[1][in_row_group_ctr];
716 inptr2 = input_buf[2][in_row_group_ctr];
717 outptr0 = output_buf[0];
718 outptr1 = output_buf[1];
719
720 /* Loop for each group of output pixels */
721 for (col = cinfo->output_width >> 1; col > 0; col--) {
722 /* Do the chroma part of the calculation */
723 cb = GETJSAMPLE(*inptr1++);
724 cr = GETJSAMPLE(*inptr2++);
725 cred = Crrtab[cr];
726 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
727 cblue = Cbbtab[cb];
728
729 /* Fetch 4 Y values and emit 4 pixels */
730 y = GETJSAMPLE(*inptr00++);
731 r = range_limit[DITHER_565_R(y + cred, d0)];
732 g = range_limit[DITHER_565_G(y + cgreen, d0)];
733 b = range_limit[DITHER_565_B(y + cblue, d0)];
734 d0 = DITHER_ROTATE(d0);
735 rgb = PACK_SHORT_565(r, g, b);
736
737 y = GETJSAMPLE(*inptr00++);
738 r = range_limit[DITHER_565_R(y + cred, d1)];
739 g = range_limit[DITHER_565_G(y + cgreen, d1)];
740 b = range_limit[DITHER_565_B(y + cblue, d1)];
741 d1 = DITHER_ROTATE(d1);
742 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
743
744 WRITE_TWO_PIXELS(outptr0, rgb);
745 outptr0 += 4;
746
747 y = GETJSAMPLE(*inptr01++);
748 r = range_limit[DITHER_565_R(y + cred, d0)];
749 g = range_limit[DITHER_565_G(y + cgreen, d0)];
750 b = range_limit[DITHER_565_B(y + cblue, d0)];
751 d0 = DITHER_ROTATE(d0);
752 rgb = PACK_SHORT_565(r, g, b);
753
754 y = GETJSAMPLE(*inptr01++);
755 r = range_limit[DITHER_565_R(y + cred, d1)];
756 g = range_limit[DITHER_565_G(y + cgreen, d1)];
757 b = range_limit[DITHER_565_B(y + cblue, d1)];
758 d1 = DITHER_ROTATE(d1);
759 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
760
761 WRITE_TWO_PIXELS(outptr1, rgb);
762 outptr1 += 4;
763 }
764
765 /* If image width is odd, do the last output column separately */
766 if (cinfo->output_width & 1) {
767 cb = GETJSAMPLE(*inptr1);
768 cr = GETJSAMPLE(*inptr2);
769 cred = Crrtab[cr];
770 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
771 cblue = Cbbtab[cb];
772
773 y = GETJSAMPLE(*inptr00);
774 r = range_limit[DITHER_565_R(y + cred, d0)];
775 g = range_limit[DITHER_565_G(y + cgreen, d0)];
776 b = range_limit[DITHER_565_B(y + cblue, d0)];
777 rgb = PACK_SHORT_565(r, g, b);
778 *(INT16*)outptr0 = rgb;
779
780 y = GETJSAMPLE(*inptr01);
781 r = range_limit[DITHER_565_R(y + cred, d1)];
782 g = range_limit[DITHER_565_G(y + cgreen, d1)];
783 b = range_limit[DITHER_565_B(y + cblue, d1)];
784 rgb = PACK_SHORT_565(r, g, b);
785 *(INT16*)outptr1 = rgb;
786 }
787}
788
789
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000790/*
791 * Module initialization routine for merged upsampling/color conversion.
792 *
793 * NB: this is called under the conditions determined by use_merged_upsample()
794 * in jdmaster.c. That routine MUST correspond to the actual capabilities
795 * of this module; no safety checks are made here.
796 */
797
Thomas G. Lane489583f1996-02-07 00:00:00 +0000798GLOBAL(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000799jinit_merged_upsampler (j_decompress_ptr cinfo)
800{
801 my_upsample_ptr upsample;
802
803 upsample = (my_upsample_ptr)
804 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DRCe5eaf372014-05-09 18:00:32 +0000805 SIZEOF(my_upsampler));
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000806 cinfo->upsample = (struct jpeg_upsampler *) upsample;
807 upsample->pub.start_pass = start_pass_merged_upsample;
808 upsample->pub.need_context_rows = FALSE;
809
810 upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
811
812 if (cinfo->max_v_samp_factor == 2) {
813 upsample->pub.upsample = merged_2v_upsample;
Pierre Ossman59a39382009-03-09 13:15:56 +0000814 if (jsimd_can_h2v2_merged_upsample())
815 upsample->upmethod = jsimd_h2v2_merged_upsample;
816 else
817 upsample->upmethod = h2v2_merged_upsample;
DRC78df2e62014-05-12 09:23:57 +0000818 if (cinfo->out_color_space == JCS_RGB565) {
819 if (cinfo->dither_mode != JDITHER_NONE) {
820 upsample->upmethod = h2v2_merged_upsample_565D;
821 } else {
822 upsample->upmethod = h2v2_merged_upsample_565;
823 }
824 }
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000825 /* Allocate a spare row buffer */
826 upsample->spare_row = (JSAMPROW)
827 (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DRCe5eaf372014-05-09 18:00:32 +0000828 (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000829 } else {
830 upsample->pub.upsample = merged_1v_upsample;
Pierre Ossman59a39382009-03-09 13:15:56 +0000831 if (jsimd_can_h2v1_merged_upsample())
832 upsample->upmethod = jsimd_h2v1_merged_upsample;
833 else
834 upsample->upmethod = h2v1_merged_upsample;
DRC78df2e62014-05-12 09:23:57 +0000835 if (cinfo->out_color_space == JCS_RGB565) {
836 if (cinfo->dither_mode != JDITHER_NONE) {
837 upsample->upmethod = h2v1_merged_upsample_565D;
838 } else {
839 upsample->upmethod = h2v1_merged_upsample_565;
840 }
841 }
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000842 /* No spare row needed */
843 upsample->spare_row = NULL;
844 }
Thomas G. Lanebc79e061995-08-02 00:00:00 +0000845
846 build_ycc_rgb_table(cinfo);
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000847}
848
849#endif /* UPSAMPLE_MERGING_SUPPORTED */