Main MRPT website > C++ reference for MRPT 1.5.7
jcdctmgr.cpp
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 #define JPEG_INTERNALS
11 #include "jinclude.h"
12 #include "mrpt_jpeglib.h"
13 #include "jdct.h" /* Private declarations for DCT subsystem */
14 
15 
16 /* Private subobject for this module */
17 
18 typedef struct {
19  struct jpeg_forward_dct pub; /* public fields */
20 
21  /* Pointer to the DCT routine actually in use */
22  forward_DCT_method_ptr do_dct;
23 
24  /* The actual post-DCT divisors --- not identical to the quant table
25  * entries, because of scaling (especially for an unnormalized DCT).
26  * Each table is given in normal array order.
27  */
28  DCTELEM * divisors[NUM_QUANT_TBLS];
29 
30 #ifdef DCT_FLOAT_SUPPORTED
31  /* Same as above for the floating-point case. */
32  float_DCT_method_ptr do_float_dct;
33  FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
34 #endif
36 
38 
39 
40 /*
41  * Initialize for a processing pass.
42  * Verify that all referenced Q-tables are present, and set up
43  * the divisor table for each one.
44  * In the current implementation, DCT of all components is done during
45  * the first pass, even if only some components will be output in the
46  * first scan. Hence all components should be examined here.
47  */
48 
49 METHODDEF(void)
51 {
52  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
53  int ci, qtblno, i;
55  JQUANT_TBL * qtbl;
56  DCTELEM * dtbl;
57 
58  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
59  ci++, compptr++) {
60  qtblno = compptr->quant_tbl_no;
61  /* Make sure specified quantization table is present */
62  if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
63  cinfo->quant_tbl_ptrs[qtblno] == NULL)
64  ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
65  qtbl = cinfo->quant_tbl_ptrs[qtblno];
66  /* Compute divisors for this quant table */
67  /* We may do this more than once for same table, but it's not a big deal */
68  switch (cinfo->dct_method) {
69 #ifdef DCT_ISLOW_SUPPORTED
70  case JDCT_ISLOW:
71  /* For LL&M IDCT method, divisors are equal to raw quantization
72  * coefficients multiplied by 8 (to counteract scaling).
73  */
74  if (fdct->divisors[qtblno] == NULL) {
75  fdct->divisors[qtblno] = (DCTELEM *)
76  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
78  }
79  dtbl = fdct->divisors[qtblno];
80  for (i = 0; i < DCTSIZE2; i++) {
81  dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
82  }
83  break;
84 #endif
85 #ifdef DCT_IFAST_SUPPORTED
86  case JDCT_IFAST:
87  {
88  /* For AA&N IDCT method, divisors are equal to quantization
89  * coefficients scaled by scalefactor[row]*scalefactor[col], where
90  * scalefactor[0] = 1
91  * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
92  * We apply a further scale factor of 8.
93  */
94 #define CONST_BITS 14
95  static const INT16 aanscales[DCTSIZE2] = {
96  /* precomputed values scaled up by 14 bits */
97  16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
98  22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
99  21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
100  19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
101  16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
102  12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
103  8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
104  4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
105  };
107 
108  if (fdct->divisors[qtblno] == NULL) {
109  fdct->divisors[qtblno] = (DCTELEM *)
110  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
111  DCTSIZE2 * SIZEOF(DCTELEM));
112  }
113  dtbl = fdct->divisors[qtblno];
114  for (i = 0; i < DCTSIZE2; i++) {
115  dtbl[i] = (DCTELEM)
116  DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
117  (INT32) aanscales[i]),
118  CONST_BITS-3);
119  }
120  }
121  break;
122 #endif
123 #ifdef DCT_FLOAT_SUPPORTED
124  case JDCT_FLOAT:
125  {
126  /* For float AA&N IDCT method, divisors are equal to quantization
127  * coefficients scaled by scalefactor[row]*scalefactor[col], where
128  * scalefactor[0] = 1
129  * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
130  * We apply a further scale factor of 8.
131  * What's actually stored is 1/divisor so that the inner loop can
132  * use a multiplication rather than a division.
133  */
134  FAST_FLOAT * fdtbl;
135  int row, col;
136  static const double aanscalefactor[DCTSIZE] = {
137  1.0, 1.387039845, 1.306562965, 1.175875602,
138  1.0, 0.785694958, 0.541196100, 0.275899379
139  };
140 
141  if (fdct->float_divisors[qtblno] == NULL) {
142  fdct->float_divisors[qtblno] = (FAST_FLOAT *)
143  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
144  DCTSIZE2 * SIZEOF(FAST_FLOAT));
145  }
146  fdtbl = fdct->float_divisors[qtblno];
147  i = 0;
148  for (row = 0; row < DCTSIZE; row++) {
149  for (col = 0; col < DCTSIZE; col++) {
150  fdtbl[i] = (FAST_FLOAT)
151  (1.0 / (((double) qtbl->quantval[i] *
152  aanscalefactor[row] * aanscalefactor[col] * 8.0)));
153  i++;
154  }
155  }
156  }
157  break;
158 #endif
159  default:
160  ERREXIT(cinfo, JERR_NOT_COMPILED);
161  break;
162  }
163  }
164 }
165 
166 
167 /*
168  * Perform forward DCT on one or more blocks of a component.
169  *
170  * The input samples are taken from the sample_data[] array starting at
171  * position start_row/start_col, and moving to the right for any additional
172  * blocks. The quantized coefficients are returned in coef_blocks[].
173  */
174 
175 METHODDEF(void)
177  JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
178  JDIMENSION start_row, JDIMENSION start_col,
180 /* This version is used for integer DCT implementations. */
181 {
182  /* This routine is heavily used, so it's worth coding it tightly. */
183  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
184  forward_DCT_method_ptr do_dct = fdct->do_dct;
185  DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
186  DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */
187  JDIMENSION bi;
188 
189  sample_data += start_row; /* fold in the vertical offset once */
190 
191  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
192  /* Load data into workspace, applying unsigned->signed conversion */
193  { DCTELEM *workspaceptr;
194  JSAMPROW elemptr;
195  int elemr;
196 
197  workspaceptr = workspace;
198  for (elemr = 0; elemr < DCTSIZE; elemr++) {
199  elemptr = sample_data[elemr] + start_col;
200 #if DCTSIZE == 8 /* unroll the inner loop */
201  *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
202  *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
203  *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
204  *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
205  *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
206  *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
207  *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
208  *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
209 #else
210  { int elemc;
211  for (elemc = DCTSIZE; elemc > 0; elemc--) {
212  *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
213  }
214  }
215 #endif
216  }
217  }
218 
219  /* Perform the DCT */
220  (*do_dct) (workspace);
221 
222  /* Quantize/descale the coefficients, and store into coef_blocks[] */
223  { DCTELEM temp, qval;
224  int i;
225  JCOEFPTR output_ptr = coef_blocks[bi];
226 
227  for (i = 0; i < DCTSIZE2; i++) {
228  qval = divisors[i];
229  temp = workspace[i];
230  /* Divide the coefficient value by qval, ensuring proper rounding.
231  * Since C does not specify the direction of rounding for negative
232  * quotients, we have to force the dividend positive for portability.
233  *
234  * In most files, at least half of the output values will be zero
235  * (at default quantization settings, more like three-quarters...)
236  * so we should ensure that this case is fast. On many machines,
237  * a comparison is enough cheaper than a divide to make a special test
238  * a win. Since both inputs will be nonnegative, we need only test
239  * for a < b to discover whether a/b is 0.
240  * If your machine's division is fast enough, define FAST_DIVIDE.
241  */
242 #ifdef FAST_DIVIDE
243 #define DIVIDE_BY(a,b) a /= b
244 #else
245 #define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0
246 #endif
247  if (temp < 0) {
248  temp = -temp;
249  temp += qval>>1; /* for rounding */
250  DIVIDE_BY(temp, qval);
251  temp = -temp;
252  } else {
253  temp += qval>>1; /* for rounding */
254  DIVIDE_BY(temp, qval);
255  }
256  output_ptr[i] = (JCOEF) temp;
257  }
258  }
259  }
260 }
261 
262 
263 #ifdef DCT_FLOAT_SUPPORTED
264 
265 METHODDEF(void)
267  JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
268  JDIMENSION start_row, JDIMENSION start_col,
270 /* This version is used for floating-point DCT implementations. */
271 {
272  /* This routine is heavily used, so it's worth coding it tightly. */
273  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
274  float_DCT_method_ptr do_dct = fdct->do_float_dct;
275  FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
276  FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */
277  JDIMENSION bi;
278 
279  sample_data += start_row; /* fold in the vertical offset once */
280 
281  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
282  /* Load data into workspace, applying unsigned->signed conversion */
283  { FAST_FLOAT *workspaceptr;
284  JSAMPROW elemptr;
285  int elemr;
286 
287  workspaceptr = workspace;
288  for (elemr = 0; elemr < DCTSIZE; elemr++) {
289  elemptr = sample_data[elemr] + start_col;
290 #if DCTSIZE == 8 /* unroll the inner loop */
291  *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
292  *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
293  *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
294  *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
295  *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
296  *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
297  *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
298  *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
299 #else
300  { int elemc;
301  for (elemc = DCTSIZE; elemc > 0; elemc--) {
302  *workspaceptr++ = (FAST_FLOAT)
303  (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
304  }
305  }
306 #endif
307  }
308  }
309 
310  /* Perform the DCT */
311  (*do_dct) (workspace);
312 
313  /* Quantize/descale the coefficients, and store into coef_blocks[] */
314  { FAST_FLOAT temp;
315  int i;
316  JCOEFPTR output_ptr = coef_blocks[bi];
317 
318  for (i = 0; i < DCTSIZE2; i++) {
319  /* Apply the quantization and scaling factor */
320  temp = workspace[i] * divisors[i];
321  /* Round to nearest integer.
322  * Since C does not specify the direction of rounding for negative
323  * quotients, we have to force the dividend positive for portability.
324  * The maximum coefficient size is +-16K (for 12-bit data), so this
325  * code should work for either 16-bit or 32-bit ints.
326  */
327  output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
328  }
329  }
330  }
331 }
332 
333 #endif /* DCT_FLOAT_SUPPORTED */
334 
335 
336 /*
337  * Initialize FDCT manager.
338  */
339 
340 GLOBAL(void)
342 {
343  my_fdct_ptr fdct;
344  int i;
345 
346  fdct = (my_fdct_ptr)
347  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
349  cinfo->fdct = (struct jpeg_forward_dct *) fdct;
350  fdct->pub.start_pass = start_pass_fdctmgr;
351 
352  switch (cinfo->dct_method) {
353 #ifdef DCT_ISLOW_SUPPORTED
354  case JDCT_ISLOW:
355  fdct->pub.forward_DCT = forward_DCT;
356  fdct->do_dct = jpeg_fdct_islow;
357  break;
358 #endif
359 #ifdef DCT_IFAST_SUPPORTED
360  case JDCT_IFAST:
361  fdct->pub.forward_DCT = forward_DCT;
362  fdct->do_dct = jpeg_fdct_ifast;
363  break;
364 #endif
365 #ifdef DCT_FLOAT_SUPPORTED
366  case JDCT_FLOAT:
367  fdct->pub.forward_DCT = forward_DCT_float;
369  break;
370 #endif
371  default:
372  ERREXIT(cinfo, JERR_NOT_COMPILED);
373  break;
374  }
375 
376  /* Mark divisor tables unallocated */
377  for (i = 0; i < NUM_QUANT_TBLS; i++) {
378  fdct->divisors[i] = NULL;
379 #ifdef DCT_FLOAT_SUPPORTED
380  fdct->float_divisors[i] = NULL;
381 #endif
382  }
383 }
#define DESCALE(x, n)
Definition: jdct.h:141
#define CENTERJSAMPLE
Definition: jmorecfg.h:71
forward_DCT_method_ptr do_dct
Definition: jcdctmgr.cpp:22
short INT16
Definition: jmorecfg.h:152
#define DIVIDE_BY(a, b)
my_fdct_controller * my_fdct_ptr
Definition: jcdctmgr.cpp:37
FAST_FLOAT * float_divisors[NUM_QUANT_TBLS]
Definition: jcdctmgr.cpp:33
#define DCTSIZE
Definition: mrpt_jpeglib.h:38
forward_DCT_float(j_compress_ptr cinfo, jpeg_component_info *compptr, JSAMPARRAY sample_data, JBLOCKROW coef_blocks, JDIMENSION start_row, JDIMENSION start_col, JDIMENSION num_blocks)
Definition: jcdctmgr.cpp:266
struct jpeg_common_struct * j_common_ptr
Definition: mrpt_jpeglib.h:258
INT32 DCTELEM
Definition: jdct.h:27
#define GETJSAMPLE(value)
Definition: jmorecfg.h:65
#define ERREXIT(cinfo, code)
Definition: jerror.h:199
#define SIZEOF(object)
Definition: jinclude.h:73
JSAMPLE FAR * JSAMPROW
Definition: mrpt_jpeglib.h:63
short JCOEF
Definition: jmorecfg.h:96
long INT32
Definition: jmorecfg.h:158
#define SHIFT_TEMPS
Definition: jpegint.h:286
jpeg_component_info * compptr
Definition: jdct.h:97
DCTELEM * divisors[NUM_QUANT_TBLS]
Definition: jcdctmgr.cpp:28
float_DCT_method_ptr do_float_dct
Definition: jcdctmgr.cpp:32
#define JPOOL_IMAGE
Definition: mrpt_jpeglib.h:746
JBLOCKROW JDIMENSION num_blocks
Definition: jpegint.h:373
JSAMPROW * JSAMPARRAY
Definition: mrpt_jpeglib.h:64
JCOEF FAR * JCOEFPTR
Definition: mrpt_jpeglib.h:72
#define DCTSIZE2
Definition: mrpt_jpeglib.h:39
struct jpeg_forward_dct pub
Definition: jcdctmgr.cpp:19
forward_DCT(j_compress_ptr cinfo, jpeg_component_info *compptr, JSAMPARRAY sample_data, JBLOCKROW coef_blocks, JDIMENSION start_row, JDIMENSION start_col, JDIMENSION num_blocks)
Definition: jcdctmgr.cpp:176
jpeg_fdct_islow(DCTELEM *data)
Definition: jfdctint.cpp:124
#define ERREXIT1(cinfo, code, p1)
Definition: jerror.h:202
jpeg_fdct_float(FAST_FLOAT *data)
Definition: jfdctflt.cpp:32
#define GLOBAL(type)
Definition: jmorecfg.h:185
jinit_forward_dct(j_compress_ptr cinfo)
Definition: jcdctmgr.cpp:341
GLenum GLenum GLvoid * row
Definition: glext.h:3533
#define METHODDEF(type)
Definition: jmorecfg.h:181
#define NUM_QUANT_TBLS
Definition: mrpt_jpeglib.h:40
jpeg_fdct_ifast(DCTELEM *data)
Definition: jfdctfst.cpp:91
JBLOCK FAR * JBLOCKROW
Definition: mrpt_jpeglib.h:68
unsigned int JDIMENSION
Definition: jmorecfg.h:168
start_pass_fdctmgr(j_compress_ptr cinfo)
Definition: jcdctmgr.cpp:50
#define CONST_BITS
#define MULTIPLY16V16(var1, var2)
Definition: jdct.h:170



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019