Main MRPT website > C++ reference for MRPT 1.5.7
jctrans.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 
14 
15 /* Forward declarations */
20 
21 
22 /*
23  * Compression initialization for writing raw-coefficient data.
24  * Before calling this, all parameters and a data destination must be set up.
25  * Call jpeg_finish_compress() to actually write the data.
26  *
27  * The number of passed virtual arrays must match cinfo->num_components.
28  * Note that the virtual arrays need not be filled or even realized at
29  * the time write_coefficients is called; indeed, if the virtual arrays
30  * were requested from this compression object's memory manager, they
31  * typically will be realized during this routine and filled afterwards.
32  */
33 
34 GLOBAL(void)
36 {
37  if (cinfo->global_state != CSTATE_START)
38  ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
39  /* Mark all tables to be written */
41  /* (Re)initialize error mgr and destination modules */
42  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
43  (*cinfo->dest->init_destination) (cinfo);
44  /* Perform master selection of active modules */
46  /* Wait for jpeg_finish_compress() call */
47  cinfo->next_scanline = 0; /* so jpeg_write_marker works */
48  cinfo->global_state = CSTATE_WRCOEFS;
49 }
50 
51 
52 /*
53  * Initialize the compression object with default parameters,
54  * then copy from the source object all parameters needed for lossless
55  * transcoding. Parameters that can be varied without loss (such as
56  * scan script and Huffman optimization) are left in their default states.
57  */
58 
59 GLOBAL(void)
62 {
63  JQUANT_TBL ** qtblptr;
64  jpeg_component_info *incomp, *outcomp;
65  JQUANT_TBL *c_quant, *slot_quant;
66  int tblno, ci, coefi;
67 
68  /* Safety check to ensure start_compress not called yet. */
69  if (dstinfo->global_state != CSTATE_START)
70  ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state);
71  /* Copy fundamental image dimensions */
72  dstinfo->image_width = srcinfo->image_width;
73  dstinfo->image_height = srcinfo->image_height;
74  dstinfo->input_components = srcinfo->num_components;
75  dstinfo->in_color_space = srcinfo->jpeg_color_space;
76  /* Initialize all parameters to default values */
78  /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
79  * Fix it to get the right header markers for the image colorspace.
80  */
82  dstinfo->data_precision = srcinfo->data_precision;
83  dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
84  /* Copy the source's quantization tables. */
85  for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
86  if (srcinfo->quant_tbl_ptrs[tblno] != NULL) {
87  qtblptr = & dstinfo->quant_tbl_ptrs[tblno];
88  if (*qtblptr == NULL)
90  MEMCOPY((*qtblptr)->quantval,
91  srcinfo->quant_tbl_ptrs[tblno]->quantval,
92  SIZEOF((*qtblptr)->quantval));
93  (*qtblptr)->sent_table = FALSE;
94  }
95  }
96  /* Copy the source's per-component info.
97  * Note we assume jpeg_set_defaults has allocated the dest comp_info array.
98  */
99  dstinfo->num_components = srcinfo->num_components;
101  ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components,
103  for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info;
104  ci < dstinfo->num_components; ci++, incomp++, outcomp++) {
105  outcomp->component_id = incomp->component_id;
106  outcomp->h_samp_factor = incomp->h_samp_factor;
107  outcomp->v_samp_factor = incomp->v_samp_factor;
108  outcomp->quant_tbl_no = incomp->quant_tbl_no;
109  /* Make sure saved quantization table for component matches the qtable
110  * slot. If not, the input file re-used this qtable slot.
111  * IJG encoder currently cannot duplicate this.
112  */
113  tblno = outcomp->quant_tbl_no;
114  if (tblno < 0 || tblno >= NUM_QUANT_TBLS ||
115  srcinfo->quant_tbl_ptrs[tblno] == NULL)
116  ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno);
117  slot_quant = srcinfo->quant_tbl_ptrs[tblno];
118  c_quant = incomp->quant_table;
119  if (c_quant != NULL) {
120  for (coefi = 0; coefi < DCTSIZE2; coefi++) {
121  if (c_quant->quantval[coefi] != slot_quant->quantval[coefi])
122  ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno);
123  }
124  }
125  /* Note: we do not copy the source's Huffman table assignments;
126  * instead we rely on jpeg_set_colorspace to have made a suitable choice.
127  */
128  }
129  /* Also copy JFIF version and resolution information, if available.
130  * Strictly speaking this isn't "critical" info, but it's nearly
131  * always appropriate to copy it if available. In particular,
132  * if the application chooses to copy JFIF 1.02 extension markers from
133  * the source file, we need to copy the version to make sure we don't
134  * emit a file that has 1.02 extensions but a claimed version of 1.01.
135  * We will *not*, however, copy version info from mislabeled "2.01" files.
136  */
137  if (srcinfo->saw_JFIF_marker) {
138  if (srcinfo->JFIF_major_version == 1) {
139  dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
140  dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
141  }
142  dstinfo->density_unit = srcinfo->density_unit;
143  dstinfo->X_density = srcinfo->X_density;
144  dstinfo->Y_density = srcinfo->Y_density;
145  }
146 }
147 
148 
149 /*
150  * Master selection of compression modules for transcoding.
151  * This substitutes for jcinit.c's initialization of the full compressor.
152  */
153 
154 LOCAL(void)
157 {
158  /* Although we don't actually use input_components for transcoding,
159  * jcmaster.c's initial_setup will complain if input_components is 0.
160  */
161  cinfo->input_components = 1;
162  /* Initialize master control (includes parameter checking/processing) */
163  jinit_c_master_control(cinfo, TRUE /* transcode only */);
164 
165  /* Entropy encoding: either Huffman or arithmetic coding. */
166  if (cinfo->arith_code) {
167  ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
168  } else {
169  if (cinfo->progressive_mode) {
170 #ifdef C_PROGRESSIVE_SUPPORTED
171  jinit_phuff_encoder(cinfo);
172 #else
173  ERREXIT(cinfo, JERR_NOT_COMPILED);
174 #endif
175  } else
176  jinit_huff_encoder(cinfo);
177  }
178 
179  /* We need a special coefficient buffer controller. */
181 
182  jinit_marker_writer(cinfo);
183 
184  /* We can now tell the memory manager to allocate virtual arrays. */
185  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
186 
187  /* Write the datastream header (SOI, JFIF) immediately.
188  * Frame and scan headers are postponed till later.
189  * This lets application insert special markers after the SOI.
190  */
191  (*cinfo->marker->write_file_header) (cinfo);
192 }
193 
194 
195 /*
196  * The rest of this file is a special implementation of the coefficient
197  * buffer controller. This is similar to jccoefct.c, but it handles only
198  * output from presupplied virtual arrays. Furthermore, we generate any
199  * dummy padding blocks on-the-fly rather than expecting them to be present
200  * in the arrays.
201  */
202 
203 /* Private buffer controller object */
204 
205 typedef struct {
206  struct jpeg_c_coef_controller pub; /* public fields */
207 
208  JDIMENSION iMCU_row_num; /* iMCU row # within image */
209  JDIMENSION mcu_ctr; /* counts MCUs processed in current row */
210  int MCU_vert_offset; /* counts MCU rows within iMCU row */
211  int MCU_rows_per_iMCU_row; /* number of such rows needed */
212 
213  /* Virtual block array for each component. */
215 
216  /* Workspace for constructing dummy blocks at right/bottom edges. */
219 
221 
222 
223 LOCAL(void)
225 /* Reset within-iMCU-row counters for a new row */
226 {
227  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
228 
229  /* In an interleaved scan, an MCU row is the same as an iMCU row.
230  * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
231  * But at the bottom of the image, process only what's left.
232  */
233  if (cinfo->comps_in_scan > 1) {
234  coef->MCU_rows_per_iMCU_row = 1;
235  } else {
236  if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
237  coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
238  else
239  coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
240  }
241 
242  coef->mcu_ctr = 0;
243  coef->MCU_vert_offset = 0;
244 }
245 
246 
247 /*
248  * Initialize for a processing pass.
249  */
250 
251 METHODDEF(void)
253 {
254  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
255 
256  if (pass_mode != JBUF_CRANK_DEST)
257  ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
258 
259  coef->iMCU_row_num = 0;
260  start_iMCU_row(cinfo);
261 }
262 
263 
264 /*
265  * Process some data.
266  * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
267  * per call, ie, v_samp_factor block rows for each component in the scan.
268  * The data is obtained from the virtual arrays and fed to the entropy coder.
269  * Returns TRUE if the iMCU row is completed, FALSE if suspended.
270  *
271  * NB: input_buf is ignored; it is likely to be a NULL pointer.
272  */
273 
274 METHODDEF(boolean)
276 {
277  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
278  JDIMENSION MCU_col_num; /* index of current MCU within row */
279  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
280  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
281  int blkn, ci, xindex, yindex, yoffset, blockcnt;
282  JDIMENSION start_col;
284  JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
285  JBLOCKROW buffer_ptr;
287 
288  /* Align the virtual buffers for the components used in this scan. */
289  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
290  compptr = cinfo->cur_comp_info[ci];
291  buffer[ci] = (*cinfo->mem->access_virt_barray)
295  }
296 
297  /* Loop to process one whole iMCU row */
298  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
299  yoffset++) {
300  for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
301  MCU_col_num++) {
302  /* Construct list of pointers to DCT blocks belonging to this MCU */
303  blkn = 0; /* index of current DCT block within MCU */
304  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
305  compptr = cinfo->cur_comp_info[ci];
306  start_col = MCU_col_num * compptr->MCU_width;
307  blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
309  for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
310  if (coef->iMCU_row_num < last_iMCU_row ||
311  yindex+yoffset < compptr->last_row_height) {
312  /* Fill in pointers to real blocks in this row */
313  buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
314  for (xindex = 0; xindex < blockcnt; xindex++)
315  MCU_buffer[blkn++] = buffer_ptr++;
316  } else {
317  /* At bottom of image, need a whole row of dummy blocks */
318  xindex = 0;
319  }
320  /* Fill in any dummy blocks needed in this row.
321  * Dummy blocks are filled in the same way as in jccoefct.c:
322  * all zeroes in the AC entries, DC entries equal to previous
323  * block's DC value. The init routine has already zeroed the
324  * AC entries, so we need only set the DC entries correctly.
325  */
326  for (; xindex < compptr->MCU_width; xindex++) {
327  MCU_buffer[blkn] = coef->dummy_buffer[blkn];
328  MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0];
329  blkn++;
330  }
331  }
332  }
333  /* Try to write the MCU. */
334  if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) {
335  /* Suspension forced; update state counters and exit */
336  coef->MCU_vert_offset = yoffset;
337  coef->mcu_ctr = MCU_col_num;
338  return FALSE;
339  }
340  }
341  /* Completed an MCU row, but perhaps not an iMCU row */
342  coef->mcu_ctr = 0;
343  }
344  /* Completed the iMCU row, advance counters for next one */
345  coef->iMCU_row_num++;
346  start_iMCU_row(cinfo);
347  return TRUE;
348 }
349 
350 
351 /*
352  * Initialize coefficient buffer controller.
353  *
354  * Each passed coefficient array must be the right size for that
355  * coefficient: width_in_blocks wide and height_in_blocks high,
356  * with unitheight at least v_samp_factor.
357  */
358 
359 LOCAL(void)
362 {
363  my_coef_ptr coef;
365  int i;
366 
367  coef = (my_coef_ptr)
368  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
370  cinfo->coef = (struct jpeg_c_coef_controller *) coef;
371  coef->pub.start_pass = start_pass_coef;
372  coef->pub.compress_data = compress_output;
373 
374  /* Save pointer to virtual arrays */
375  coef->whole_image = coef_arrays;
376 
377  /* Allocate and pre-zero space for dummy DCT blocks. */
378  buffer = (JBLOCKROW)
379  (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
382  for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
383  coef->dummy_buffer[i] = buffer + i;
384  }
385 }
jzero_far(void FAR *target, size_t bytestozero)
Definition: jutils.cpp:161
UINT16 quantval[DCTSIZE2]
Definition: mrpt_jpeglib.h:85
#define CSTATE_START
Definition: jpegint.h:22
J_COLOR_SPACE jpeg_color_space
Definition: mrpt_jpeglib.h:294
jpeg_write_coefficients(j_compress_ptr cinfo, jvirt_barray_ptr *coef_arrays)
Definition: jctrans.cpp:35
GLuint buffer
Definition: glext.h:3775
#define MAX_COMPS_IN_SCAN
Definition: mrpt_jpeglib.h:43
jpeg_set_defaults(j_compress_ptr cinfo)
Definition: jcparam.cpp:265
struct jpeg_common_struct * j_common_ptr
Definition: mrpt_jpeglib.h:258
JDIMENSION image_height
Definition: mrpt_jpeglib.h:277
#define MAX_COMPONENTS
Definition: jmorecfg.h:32
JDIMENSION mcu_ctr
Definition: jccoefct.cpp:35
#define ERREXIT(cinfo, code)
Definition: jerror.h:199
#define SIZEOF(object)
Definition: jinclude.h:73
jpeg_suppress_tables(j_compress_ptr cinfo, boolean suppress)
Definition: jcapimin.cpp:110
start_iMCU_row(j_compress_ptr cinfo)
Definition: jctrans.cpp:224
jpeg_component_info * compptr
Definition: jdct.h:97
jvirt_barray_ptr * coef_arrays
Definition: jctrans.cpp:17
J_COLOR_SPACE in_color_space
Definition: mrpt_jpeglib.h:279
jinit_phuff_encoder(j_compress_ptr cinfo)
Definition: jcphuff.cpp:809
jpeg_copy_critical_parameters(j_decompress_ptr srcinfo, j_compress_ptr dstinfo)
Definition: jctrans.cpp:60
struct jpeg_c_coef_controller pub
Definition: jccoefct.cpp:32
jinit_huff_encoder(j_compress_ptr cinfo)
Definition: jchuff.cpp:884
#define MEMCOPY(dest, src, size)
Definition: jinclude.h:61
jpeg_set_colorspace(j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
Definition: jcparam.cpp:388
GLint GLint GLint yoffset
Definition: glext.h:3546
#define FALSE
Definition: jmorecfg.h:227
jvirt_barray_ptr * whole_image
Definition: jctrans.cpp:214
#define JPOOL_IMAGE
Definition: mrpt_jpeglib.h:746
my_coef_controller * my_coef_ptr
Definition: jctrans.cpp:220
JDIMENSION iMCU_row_num
Definition: jccoefct.cpp:34
#define DCTSIZE2
Definition: mrpt_jpeglib.h:39
#define JPP(arglist)
Definition: mrpt_jpeglib.h:815
#define TRUE
Definition: jmorecfg.h:230
JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU]
Definition: jctrans.cpp:217
jpeg_alloc_quant_table(j_common_ptr cinfo)
Definition: jcomapi.cpp:84
#define C_MAX_BLOCKS_IN_MCU
Definition: mrpt_jpeglib.h:52
JQUANT_TBL * quant_table
Definition: mrpt_jpeglib.h:172
#define ERREXIT1(cinfo, code, p1)
Definition: jerror.h:202
JSAMPARRAY * JSAMPIMAGE
Definition: mrpt_jpeglib.h:65
j_compress_ptr dstinfo
JBLOCKROW * JBLOCKARRAY
Definition: mrpt_jpeglib.h:69
start_pass_coef(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
Definition: jctrans.cpp:252
#define GLOBAL(type)
Definition: jmorecfg.h:185
JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]
Definition: mrpt_jpeglib.h:299
#define METHODDEF(type)
Definition: jmorecfg.h:181
#define NUM_QUANT_TBLS
Definition: mrpt_jpeglib.h:40
transencode_coef_controller(j_compress_ptr cinfo, jvirt_barray_ptr *coef_arrays)
Definition: jctrans.cpp:360
J_BUF_MODE
Definition: jpegint.h:13
transencode_master_selection(j_compress_ptr cinfo, jvirt_barray_ptr *coef_arrays)
Definition: jctrans.cpp:155
JBLOCK FAR * JBLOCKROW
Definition: mrpt_jpeglib.h:68
jinit_c_master_control(j_compress_ptr cinfo, boolean transcode_only)
Definition: jcmaster.cpp:539
unsigned int JDIMENSION
Definition: jmorecfg.h:168
#define FAR
Definition: zconf.h:261
#define CSTATE_WRCOEFS
Definition: jpegint.h:25
#define ERREXIT2(cinfo, code, p1, p2)
Definition: jerror.h:206
boolean int tblno
Definition: jchuff.h:39
jinit_marker_writer(j_compress_ptr cinfo)
Definition: jcmarker.cpp:644
JCOEF JBLOCK[DCTSIZE2]
Definition: mrpt_jpeglib.h:67
LOCAL(void) transencode_master_selection JPP((j_compress_ptr cinfo
jpeg_component_info * comp_info
Definition: mrpt_jpeglib.h:296
compress_output(j_compress_ptr cinfo, JSAMPIMAGE)
Definition: jctrans.cpp:275
jvirt_barray_ptr whole_image[MAX_COMPONENTS]
Definition: jccoefct.cpp:51
JDIMENSION image_width
Definition: mrpt_jpeglib.h:276



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