Remove 'oldcode'
[oweals/cde.git] / cde / lib / DtHelp / jpeg / jdmerge.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: jdmerge.c /main/2 1996/05/09 03:49:11 drk $ */
24 /*
25  * jdmerge.c
26  *
27  * Copyright (C) 1994-1996, Thomas G. Lane.
28  * This file is part of the Independent JPEG Group's software.
29  * For conditions of distribution and use, see the accompanying README file.
30  *
31  * This file contains code for merged upsampling/color conversion.
32  *
33  * This file combines functions from jdsample.c and jdcolor.c;
34  * read those files first to understand what's going on.
35  *
36  * When the chroma components are to be upsampled by simple replication
37  * (ie, box filtering), we can save some work in color conversion by
38  * calculating all the output pixels corresponding to a pair of chroma
39  * samples at one time.  In the conversion equations
40  *      R = Y           + K1 * Cr
41  *      G = Y + K2 * Cb + K3 * Cr
42  *      B = Y + K4 * Cb
43  * only the Y term varies among the group of pixels corresponding to a pair
44  * of chroma samples, so the rest of the terms can be calculated just once.
45  * At typical sampling ratios, this eliminates half or three-quarters of the
46  * multiplications needed for color conversion.
47  *
48  * This file currently provides implementations for the following cases:
49  *      YCbCr => RGB color conversion only.
50  *      Sampling ratios of 2h1v or 2h2v.
51  *      No scaling needed at upsample time.
52  *      Corner-aligned (non-CCIR601) sampling alignment.
53  * Other special cases could be added, but in most applications these are
54  * the only common cases.  (For uncommon cases we fall back on the more
55  * general code in jdsample.c and jdcolor.c.)
56  */
57
58 #define JPEG_INTERNALS
59 #include "jinclude.h"
60 #include "jpeglib.h"
61
62 #ifdef UPSAMPLE_MERGING_SUPPORTED
63
64
65 /* Private subobject */
66
67 typedef struct {
68   struct jpeg_upsampler pub;    /* public fields */
69
70   /* Pointer to routine to do actual upsampling/conversion of one row group */
71   JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
72                            JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
73                            JSAMPARRAY output_buf));
74
75   /* Private state for YCC->RGB conversion */
76   int * Cr_r_tab;               /* => table for Cr to R conversion */
77   int * Cb_b_tab;               /* => table for Cb to B conversion */
78   INT32 * Cr_g_tab;             /* => table for Cr to G conversion */
79   INT32 * Cb_g_tab;             /* => table for Cb to G conversion */
80
81   /* For 2:1 vertical sampling, we produce two output rows at a time.
82    * We need a "spare" row buffer to hold the second output row if the
83    * application provides just a one-row buffer; we also use the spare
84    * to discard the dummy last row if the image height is odd.
85    */
86   JSAMPROW spare_row;
87   boolean spare_full;           /* T if spare buffer is occupied */
88
89   JDIMENSION out_row_width;     /* samples per output row */
90   JDIMENSION rows_to_go;        /* counts rows remaining in image */
91 } my_upsampler;
92
93 typedef my_upsampler * my_upsample_ptr;
94
95 #define SCALEBITS       16      /* speediest right-shift on some machines */
96 #define ONE_HALF        ((INT32) 1 << (SCALEBITS-1))
97 #define FIX(x)          ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
98
99
100 /*
101  * Initialize tables for YCC->RGB colorspace conversion.
102  * This is taken directly from jdcolor.c; see that file for more info.
103  */
104
105 LOCAL(void)
106 build_ycc_rgb_table (j_decompress_ptr cinfo)
107 {
108   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
109   int i;
110   INT32 x;
111   SHIFT_TEMPS
112
113   upsample->Cr_r_tab = (int *)
114     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
115                                 (MAXJSAMPLE+1) * SIZEOF(int));
116   upsample->Cb_b_tab = (int *)
117     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
118                                 (MAXJSAMPLE+1) * SIZEOF(int));
119   upsample->Cr_g_tab = (INT32 *)
120     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
121                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
122   upsample->Cb_g_tab = (INT32 *)
123     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
124                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
125
126   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
127     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
128     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
129     /* Cr=>R value is nearest int to 1.40200 * x */
130     upsample->Cr_r_tab[i] = (int)
131                     RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
132     /* Cb=>B value is nearest int to 1.77200 * x */
133     upsample->Cb_b_tab[i] = (int)
134                     RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
135     /* Cr=>G value is scaled-up -0.71414 * x */
136     upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
137     /* Cb=>G value is scaled-up -0.34414 * x */
138     /* We also add in ONE_HALF so that need not do it in inner loop */
139     upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
140   }
141 }
142
143
144 /*
145  * Initialize for an upsampling pass.
146  */
147
148 METHODDEF(void)
149 start_pass_merged_upsample (j_decompress_ptr cinfo)
150 {
151   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
152
153   /* Mark the spare buffer empty */
154   upsample->spare_full = FALSE;
155   /* Initialize total-height counter for detecting bottom of image */
156   upsample->rows_to_go = cinfo->output_height;
157 }
158
159
160 /*
161  * Control routine to do upsampling (and color conversion).
162  *
163  * The control routine just handles the row buffering considerations.
164  */
165
166 METHODDEF(void)
167 merged_2v_upsample (j_decompress_ptr cinfo,
168                     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
169                     JDIMENSION in_row_groups_avail,
170                     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
171                     JDIMENSION out_rows_avail)
172 /* 2:1 vertical sampling case: may need a spare row. */
173 {
174   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
175   JSAMPROW work_ptrs[2];
176   JDIMENSION num_rows;          /* number of rows returned to caller */
177
178   if (upsample->spare_full) {
179     /* If we have a spare row saved from a previous cycle, just return it. */
180     jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
181                       1, upsample->out_row_width);
182     num_rows = 1;
183     upsample->spare_full = FALSE;
184   } else {
185     /* Figure number of rows to return to caller. */
186     num_rows = 2;
187     /* Not more than the distance to the end of the image. */
188     if (num_rows > upsample->rows_to_go)
189       num_rows = upsample->rows_to_go;
190     /* And not more than what the client can accept: */
191     out_rows_avail -= *out_row_ctr;
192     if (num_rows > out_rows_avail)
193       num_rows = out_rows_avail;
194     /* Create output pointer array for upsampler. */
195     work_ptrs[0] = output_buf[*out_row_ctr];
196     if (num_rows > 1) {
197       work_ptrs[1] = output_buf[*out_row_ctr + 1];
198     } else {
199       work_ptrs[1] = upsample->spare_row;
200       upsample->spare_full = TRUE;
201     }
202     /* Now do the upsampling. */
203     (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
204   }
205
206   /* Adjust counts */
207   *out_row_ctr += num_rows;
208   upsample->rows_to_go -= num_rows;
209   /* When the buffer is emptied, declare this input row group consumed */
210   if (! upsample->spare_full)
211     (*in_row_group_ctr)++;
212 }
213
214
215 METHODDEF(void)
216 merged_1v_upsample (j_decompress_ptr cinfo,
217                     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
218                     JDIMENSION in_row_groups_avail,
219                     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
220                     JDIMENSION out_rows_avail)
221 /* 1:1 vertical sampling case: much easier, never need a spare row. */
222 {
223   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
224
225   /* Just do the upsampling. */
226   (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
227                          output_buf + *out_row_ctr);
228   /* Adjust counts */
229   (*out_row_ctr)++;
230   (*in_row_group_ctr)++;
231 }
232
233
234 /*
235  * These are the routines invoked by the control routines to do
236  * the actual upsampling/conversion.  One row group is processed per call.
237  *
238  * Note: since we may be writing directly into application-supplied buffers,
239  * we have to be honest about the output width; we can't assume the buffer
240  * has been rounded up to an even width.
241  */
242
243
244 /*
245  * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
246  */
247
248 METHODDEF(void)
249 h2v1_merged_upsample (j_decompress_ptr cinfo,
250                       JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
251                       JSAMPARRAY output_buf)
252 {
253   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
254   int y, cred, cgreen, cblue;
255   int cb, cr;
256   JSAMPROW outptr;
257   JSAMPROW inptr0, inptr1, inptr2;
258   JDIMENSION col;
259   /* copy these pointers into registers if possible */
260   JSAMPLE * range_limit = cinfo->sample_range_limit;
261   int * Crrtab = upsample->Cr_r_tab;
262   int * Cbbtab = upsample->Cb_b_tab;
263   INT32 * Crgtab = upsample->Cr_g_tab;
264   INT32 * Cbgtab = upsample->Cb_g_tab;
265   SHIFT_TEMPS
266
267   inptr0 = input_buf[0][in_row_group_ctr];
268   inptr1 = input_buf[1][in_row_group_ctr];
269   inptr2 = input_buf[2][in_row_group_ctr];
270   outptr = output_buf[0];
271   /* Loop for each pair of output pixels */
272   for (col = cinfo->output_width >> 1; col > 0; col--) {
273     /* Do the chroma part of the calculation */
274     cb = GETJSAMPLE(*inptr1++);
275     cr = GETJSAMPLE(*inptr2++);
276     cred = Crrtab[cr];
277     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
278     cblue = Cbbtab[cb];
279     /* Fetch 2 Y values and emit 2 pixels */
280     y  = GETJSAMPLE(*inptr0++);
281     outptr[RGB_RED] =   range_limit[y + cred];
282     outptr[RGB_GREEN] = range_limit[y + cgreen];
283     outptr[RGB_BLUE] =  range_limit[y + cblue];
284     outptr += RGB_PIXELSIZE;
285     y  = GETJSAMPLE(*inptr0++);
286     outptr[RGB_RED] =   range_limit[y + cred];
287     outptr[RGB_GREEN] = range_limit[y + cgreen];
288     outptr[RGB_BLUE] =  range_limit[y + cblue];
289     outptr += RGB_PIXELSIZE;
290   }
291   /* If image width is odd, do the last output column separately */
292   if (cinfo->output_width & 1) {
293     cb = GETJSAMPLE(*inptr1);
294     cr = GETJSAMPLE(*inptr2);
295     cred = Crrtab[cr];
296     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
297     cblue = Cbbtab[cb];
298     y  = GETJSAMPLE(*inptr0);
299     outptr[RGB_RED] =   range_limit[y + cred];
300     outptr[RGB_GREEN] = range_limit[y + cgreen];
301     outptr[RGB_BLUE] =  range_limit[y + cblue];
302   }
303 }
304
305
306 /*
307  * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
308  */
309
310 METHODDEF(void)
311 h2v2_merged_upsample (j_decompress_ptr cinfo,
312                       JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
313                       JSAMPARRAY output_buf)
314 {
315   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
316   int y, cred, cgreen, cblue;
317   int cb, cr;
318   JSAMPROW outptr0, outptr1;
319   JSAMPROW inptr00, inptr01, inptr1, inptr2;
320   JDIMENSION col;
321   /* copy these pointers into registers if possible */
322   JSAMPLE * range_limit = cinfo->sample_range_limit;
323   int * Crrtab = upsample->Cr_r_tab;
324   int * Cbbtab = upsample->Cb_b_tab;
325   INT32 * Crgtab = upsample->Cr_g_tab;
326   INT32 * Cbgtab = upsample->Cb_g_tab;
327   SHIFT_TEMPS
328
329   inptr00 = input_buf[0][in_row_group_ctr*2];
330   inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
331   inptr1 = input_buf[1][in_row_group_ctr];
332   inptr2 = input_buf[2][in_row_group_ctr];
333   outptr0 = output_buf[0];
334   outptr1 = output_buf[1];
335   /* Loop for each group of output pixels */
336   for (col = cinfo->output_width >> 1; col > 0; col--) {
337     /* Do the chroma part of the calculation */
338     cb = GETJSAMPLE(*inptr1++);
339     cr = GETJSAMPLE(*inptr2++);
340     cred = Crrtab[cr];
341     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
342     cblue = Cbbtab[cb];
343     /* Fetch 4 Y values and emit 4 pixels */
344     y  = GETJSAMPLE(*inptr00++);
345     outptr0[RGB_RED] =   range_limit[y + cred];
346     outptr0[RGB_GREEN] = range_limit[y + cgreen];
347     outptr0[RGB_BLUE] =  range_limit[y + cblue];
348     outptr0 += RGB_PIXELSIZE;
349     y  = GETJSAMPLE(*inptr00++);
350     outptr0[RGB_RED] =   range_limit[y + cred];
351     outptr0[RGB_GREEN] = range_limit[y + cgreen];
352     outptr0[RGB_BLUE] =  range_limit[y + cblue];
353     outptr0 += RGB_PIXELSIZE;
354     y  = GETJSAMPLE(*inptr01++);
355     outptr1[RGB_RED] =   range_limit[y + cred];
356     outptr1[RGB_GREEN] = range_limit[y + cgreen];
357     outptr1[RGB_BLUE] =  range_limit[y + cblue];
358     outptr1 += RGB_PIXELSIZE;
359     y  = GETJSAMPLE(*inptr01++);
360     outptr1[RGB_RED] =   range_limit[y + cred];
361     outptr1[RGB_GREEN] = range_limit[y + cgreen];
362     outptr1[RGB_BLUE] =  range_limit[y + cblue];
363     outptr1 += RGB_PIXELSIZE;
364   }
365   /* If image width is odd, do the last output column separately */
366   if (cinfo->output_width & 1) {
367     cb = GETJSAMPLE(*inptr1);
368     cr = GETJSAMPLE(*inptr2);
369     cred = Crrtab[cr];
370     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
371     cblue = Cbbtab[cb];
372     y  = GETJSAMPLE(*inptr00);
373     outptr0[RGB_RED] =   range_limit[y + cred];
374     outptr0[RGB_GREEN] = range_limit[y + cgreen];
375     outptr0[RGB_BLUE] =  range_limit[y + cblue];
376     y  = GETJSAMPLE(*inptr01);
377     outptr1[RGB_RED] =   range_limit[y + cred];
378     outptr1[RGB_GREEN] = range_limit[y + cgreen];
379     outptr1[RGB_BLUE] =  range_limit[y + cblue];
380   }
381 }
382
383
384 /*
385  * Module initialization routine for merged upsampling/color conversion.
386  *
387  * NB: this is called under the conditions determined by use_merged_upsample()
388  * in jdmaster.c.  That routine MUST correspond to the actual capabilities
389  * of this module; no safety checks are made here.
390  */
391
392 GLOBAL(void)
393 jinit_merged_upsampler (j_decompress_ptr cinfo)
394 {
395   my_upsample_ptr upsample;
396
397   upsample = (my_upsample_ptr)
398     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
399                                 SIZEOF(my_upsampler));
400   cinfo->upsample = (struct jpeg_upsampler *) upsample;
401   upsample->pub.start_pass = start_pass_merged_upsample;
402   upsample->pub.need_context_rows = FALSE;
403
404   upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
405
406   if (cinfo->max_v_samp_factor == 2) {
407     upsample->pub.upsample = merged_2v_upsample;
408     upsample->upmethod = h2v2_merged_upsample;
409     /* Allocate a spare row buffer */
410     upsample->spare_row = (JSAMPROW)
411       (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
412                 (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
413   } else {
414     upsample->pub.upsample = merged_1v_upsample;
415     upsample->upmethod = h2v1_merged_upsample;
416     /* No spare row needed */
417     upsample->spare_row = NULL;
418   }
419
420   build_ycc_rgb_table(cinfo);
421 }
422
423 #endif /* UPSAMPLE_MERGING_SUPPORTED */