Main MRPT website > C++ reference for MRPT 1.5.6
transupp.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 /* Although this file really shouldn't have access to the library internals,
11  * it's helpful to let it call jround_up() and jcopy_block_row().
12  */
13 #define JPEG_INTERNALS
14 
15 #include "jinclude.h"
16 #include "mrpt_jpeglib.h"
17 #include "transupp.h" /* My own external interface */
18 
19 
20 #if TRANSFORMS_SUPPORTED
21 
22 /*
23  * Lossless image transformation routines. These routines work on DCT
24  * coefficient arrays and thus do not require any lossy decompression
25  * or recompression of the image.
26  * Thanks to Guido Vollbeding for the initial design and code of this feature.
27  *
28  * Horizontal flipping is done in-place, using a single top-to-bottom
29  * pass through the virtual source array. It will thus be much the
30  * fastest option for images larger than main memory.
31  *
32  * The other routines require a set of destination virtual arrays, so they
33  * need twice as much memory as jpegtran normally does. The destination
34  * arrays are always written in normal scan order (top to bottom) because
35  * the virtual array manager expects this. The source arrays will be scanned
36  * in the corresponding order, which means multiple passes through the source
37  * arrays for most of the transforms. That could result in much thrashing
38  * if the image is larger than main memory.
39  *
40  * Some notes about the operating environment of the individual transform
41  * routines:
42  * 1. Both the source and destination virtual arrays are allocated from the
43  * source JPEG object, and therefore should be manipulated by calling the
44  * source's memory manager.
45  * 2. The destination's component count should be used. It may be smaller
46  * than the source's when forcing to grayscale.
47  * 3. Likewise the destination's sampling factors should be used. When
48  * forcing to grayscale the destination's sampling factors will be all 1,
49  * and we may as well take that as the effective iMCU size.
50  * 4. When "trim" is in effect, the destination's dimensions will be the
51  * trimmed values but the source's will be untrimmed.
52  * 5. All the routines assume that the source and destination buffers are
53  * padded out to a full iMCU boundary. This is true, although for the
54  * source buffer it is an undocumented property of jdcoefct.c.
55  * Notes 2,3,4 boil down to this: generally we should use the destination's
56  * dimensions and ignore the source's.
57  */
58 
59 
60 LOCAL(void)
61 do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
62  jvirt_barray_ptr *src_coef_arrays)
63 /* Horizontal flip; done in-place, so no separate dest array is required */
64 {
65  JDIMENSION MCU_cols, comp_width, blk_x, blk_y;
66  int ci, k, offset_y;
68  JCOEFPTR ptr1, ptr2;
69  JCOEF temp1, temp2;
71 
72  /* Horizontal mirroring of DCT blocks is accomplished by swapping
73  * pairs of blocks in-place. Within a DCT block, we perform horizontal
74  * mirroring by changing the signs of odd-numbered columns.
75  * Partial iMCUs at the right edge are left untouched.
76  */
77  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
78 
79  for (ci = 0; ci < dstinfo->num_components; ci++) {
80  compptr = dstinfo->comp_info + ci;
81  comp_width = MCU_cols * compptr->h_samp_factor;
82  for (blk_y = 0; blk_y < compptr->height_in_blocks;
83  blk_y += compptr->v_samp_factor) {
84  buffer = (*srcinfo->mem->access_virt_barray)
85  ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y,
86  (JDIMENSION) compptr->v_samp_factor, TRUE);
87  for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
88  for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) {
89  ptr1 = buffer[offset_y][blk_x];
90  ptr2 = buffer[offset_y][comp_width - blk_x - 1];
91  /* this unrolled loop doesn't need to know which row it's on... */
92  for (k = 0; k < DCTSIZE2; k += 2) {
93  temp1 = *ptr1; /* swap even column */
94  temp2 = *ptr2;
95  *ptr1++ = temp2;
96  *ptr2++ = temp1;
97  temp1 = *ptr1; /* swap odd column with sign change */
98  temp2 = *ptr2;
99  *ptr1++ = -temp2;
100  *ptr2++ = -temp1;
101  }
102  }
103  }
104  }
105  }
106 }
107 
108 
109 LOCAL(void)
110 do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
111  jvirt_barray_ptr *src_coef_arrays,
112  jvirt_barray_ptr *dst_coef_arrays)
113 /* Vertical flip */
114 {
115  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
116  int ci, i, j, offset_y;
117  JBLOCKARRAY src_buffer, dst_buffer;
118  JBLOCKROW src_row_ptr, dst_row_ptr;
119  JCOEFPTR src_ptr, dst_ptr;
121 
122  /* We output into a separate array because we can't touch different
123  * rows of the source virtual array simultaneously. Otherwise, this
124  * is a pretty straightforward analog of horizontal flip.
125  * Within a DCT block, vertical mirroring is done by changing the signs
126  * of odd-numbered rows.
127  * Partial iMCUs at the bottom edge are copied verbatim.
128  */
129  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
130 
131  for (ci = 0; ci < dstinfo->num_components; ci++) {
132  compptr = dstinfo->comp_info + ci;
133  comp_height = MCU_rows * compptr->v_samp_factor;
134  for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
135  dst_blk_y += compptr->v_samp_factor) {
136  dst_buffer = (*srcinfo->mem->access_virt_barray)
137  ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
138  (JDIMENSION) compptr->v_samp_factor, TRUE);
139  if (dst_blk_y < comp_height) {
140  /* Row is within the mirrorable area. */
141  src_buffer = (*srcinfo->mem->access_virt_barray)
142  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
143  comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor,
144  (JDIMENSION) compptr->v_samp_factor, FALSE);
145  } else {
146  /* Bottom-edge blocks will be copied verbatim. */
147  src_buffer = (*srcinfo->mem->access_virt_barray)
148  ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y,
149  (JDIMENSION) compptr->v_samp_factor, FALSE);
150  }
151  for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
152  if (dst_blk_y < comp_height) {
153  /* Row is within the mirrorable area. */
154  dst_row_ptr = dst_buffer[offset_y];
155  src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
156  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
157  dst_blk_x++) {
158  dst_ptr = dst_row_ptr[dst_blk_x];
159  src_ptr = src_row_ptr[dst_blk_x];
160  for (i = 0; i < DCTSIZE; i += 2) {
161  /* copy even row */
162  for (j = 0; j < DCTSIZE; j++)
163  *dst_ptr++ = *src_ptr++;
164  /* copy odd row with sign change */
165  for (j = 0; j < DCTSIZE; j++)
166  *dst_ptr++ = - *src_ptr++;
167  }
168  }
169  } else {
170  /* Just copy row verbatim. */
171  jcopy_block_row(src_buffer[offset_y], dst_buffer[offset_y],
172  compptr->width_in_blocks);
173  }
174  }
175  }
176  }
177 }
178 
179 
180 LOCAL(void)
181 do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
182  jvirt_barray_ptr *src_coef_arrays,
183  jvirt_barray_ptr *dst_coef_arrays)
184 /* Transpose source into destination */
185 {
186  JDIMENSION dst_blk_x, dst_blk_y;
187  int ci, i, j, offset_x, offset_y;
188  JBLOCKARRAY src_buffer, dst_buffer;
189  JCOEFPTR src_ptr, dst_ptr;
191 
192  /* Transposing pixels within a block just requires transposing the
193  * DCT coefficients.
194  * Partial iMCUs at the edges require no special treatment; we simply
195  * process all the available DCT blocks for every component.
196  */
197  for (ci = 0; ci < dstinfo->num_components; ci++) {
198  compptr = dstinfo->comp_info + ci;
199  for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
200  dst_blk_y += compptr->v_samp_factor) {
201  dst_buffer = (*srcinfo->mem->access_virt_barray)
202  ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
203  (JDIMENSION) compptr->v_samp_factor, TRUE);
204  for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
205  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
206  dst_blk_x += compptr->h_samp_factor) {
207  src_buffer = (*srcinfo->mem->access_virt_barray)
208  ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
209  (JDIMENSION) compptr->h_samp_factor, FALSE);
210  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
211  src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
212  dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
213  for (i = 0; i < DCTSIZE; i++)
214  for (j = 0; j < DCTSIZE; j++)
215  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
216  }
217  }
218  }
219  }
220  }
221 }
222 
223 
224 LOCAL(void)
225 do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
226  jvirt_barray_ptr *src_coef_arrays,
227  jvirt_barray_ptr *dst_coef_arrays)
228 /* 90 degree rotation is equivalent to
229  * 1. Transposing the image;
230  * 2. Horizontal mirroring.
231  * These two steps are merged into a single processing routine.
232  */
233 {
234  JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
235  int ci, i, j, offset_x, offset_y;
236  JBLOCKARRAY src_buffer, dst_buffer;
237  JCOEFPTR src_ptr, dst_ptr;
239 
240  /* Because of the horizontal mirror step, we can't process partial iMCUs
241  * at the (output) right edge properly. They just get transposed and
242  * not mirrored.
243  */
244  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
245 
246  for (ci = 0; ci < dstinfo->num_components; ci++) {
247  compptr = dstinfo->comp_info + ci;
248  comp_width = MCU_cols * compptr->h_samp_factor;
249  for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
250  dst_blk_y += compptr->v_samp_factor) {
251  dst_buffer = (*srcinfo->mem->access_virt_barray)
252  ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
253  (JDIMENSION) compptr->v_samp_factor, TRUE);
254  for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
255  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
256  dst_blk_x += compptr->h_samp_factor) {
257  src_buffer = (*srcinfo->mem->access_virt_barray)
258  ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
259  (JDIMENSION) compptr->h_samp_factor, FALSE);
260  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
261  src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
262  if (dst_blk_x < comp_width) {
263  /* Block is within the mirrorable area. */
264  dst_ptr = dst_buffer[offset_y]
265  [comp_width - dst_blk_x - offset_x - 1];
266  for (i = 0; i < DCTSIZE; i++) {
267  for (j = 0; j < DCTSIZE; j++)
268  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
269  i++;
270  for (j = 0; j < DCTSIZE; j++)
271  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
272  }
273  } else {
274  /* Edge blocks are transposed but not mirrored. */
275  dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
276  for (i = 0; i < DCTSIZE; i++)
277  for (j = 0; j < DCTSIZE; j++)
278  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
279  }
280  }
281  }
282  }
283  }
284  }
285 }
286 
287 
288 LOCAL(void)
289 do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
290  jvirt_barray_ptr *src_coef_arrays,
291  jvirt_barray_ptr *dst_coef_arrays)
292 /* 270 degree rotation is equivalent to
293  * 1. Horizontal mirroring;
294  * 2. Transposing the image.
295  * These two steps are merged into a single processing routine.
296  */
297 {
298  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
299  int ci, i, j, offset_x, offset_y;
300  JBLOCKARRAY src_buffer, dst_buffer;
301  JCOEFPTR src_ptr, dst_ptr;
303 
304  /* Because of the horizontal mirror step, we can't process partial iMCUs
305  * at the (output) bottom edge properly. They just get transposed and
306  * not mirrored.
307  */
308  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
309 
310  for (ci = 0; ci < dstinfo->num_components; ci++) {
311  compptr = dstinfo->comp_info + ci;
312  comp_height = MCU_rows * compptr->v_samp_factor;
313  for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
314  dst_blk_y += compptr->v_samp_factor) {
315  dst_buffer = (*srcinfo->mem->access_virt_barray)
316  ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
317  (JDIMENSION) compptr->v_samp_factor, TRUE);
318  for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
319  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
320  dst_blk_x += compptr->h_samp_factor) {
321  src_buffer = (*srcinfo->mem->access_virt_barray)
322  ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
323  (JDIMENSION) compptr->h_samp_factor, FALSE);
324  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
325  dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
326  if (dst_blk_y < comp_height) {
327  /* Block is within the mirrorable area. */
328  src_ptr = src_buffer[offset_x]
329  [comp_height - dst_blk_y - offset_y - 1];
330  for (i = 0; i < DCTSIZE; i++) {
331  for (j = 0; j < DCTSIZE; j++) {
332  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
333  j++;
334  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
335  }
336  }
337  } else {
338  /* Edge blocks are transposed but not mirrored. */
339  src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
340  for (i = 0; i < DCTSIZE; i++)
341  for (j = 0; j < DCTSIZE; j++)
342  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
343  }
344  }
345  }
346  }
347  }
348  }
349 }
350 
351 
352 LOCAL(void)
353 do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
354  jvirt_barray_ptr *src_coef_arrays,
355  jvirt_barray_ptr *dst_coef_arrays)
356 /* 180 degree rotation is equivalent to
357  * 1. Vertical mirroring;
358  * 2. Horizontal mirroring.
359  * These two steps are merged into a single processing routine.
360  */
361 {
362  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
363  int ci, i, j, offset_y;
364  JBLOCKARRAY src_buffer, dst_buffer;
365  JBLOCKROW src_row_ptr, dst_row_ptr;
366  JCOEFPTR src_ptr, dst_ptr;
368 
369  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
370  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
371 
372  for (ci = 0; ci < dstinfo->num_components; ci++) {
373  compptr = dstinfo->comp_info + ci;
374  comp_width = MCU_cols * compptr->h_samp_factor;
375  comp_height = MCU_rows * compptr->v_samp_factor;
376  for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
377  dst_blk_y += compptr->v_samp_factor) {
378  dst_buffer = (*srcinfo->mem->access_virt_barray)
379  ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
380  (JDIMENSION) compptr->v_samp_factor, TRUE);
381  if (dst_blk_y < comp_height) {
382  /* Row is within the vertically mirrorable area. */
383  src_buffer = (*srcinfo->mem->access_virt_barray)
384  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
385  comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor,
386  (JDIMENSION) compptr->v_samp_factor, FALSE);
387  } else {
388  /* Bottom-edge rows are only mirrored horizontally. */
389  src_buffer = (*srcinfo->mem->access_virt_barray)
390  ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y,
391  (JDIMENSION) compptr->v_samp_factor, FALSE);
392  }
393  for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
394  if (dst_blk_y < comp_height) {
395  /* Row is within the mirrorable area. */
396  dst_row_ptr = dst_buffer[offset_y];
397  src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
398  /* Process the blocks that can be mirrored both ways. */
399  for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
400  dst_ptr = dst_row_ptr[dst_blk_x];
401  src_ptr = src_row_ptr[comp_width - dst_blk_x - 1];
402  for (i = 0; i < DCTSIZE; i += 2) {
403  /* For even row, negate every odd column. */
404  for (j = 0; j < DCTSIZE; j += 2) {
405  *dst_ptr++ = *src_ptr++;
406  *dst_ptr++ = - *src_ptr++;
407  }
408  /* For odd row, negate every even column. */
409  for (j = 0; j < DCTSIZE; j += 2) {
410  *dst_ptr++ = - *src_ptr++;
411  *dst_ptr++ = *src_ptr++;
412  }
413  }
414  }
415  /* Any remaining right-edge blocks are only mirrored vertically. */
416  for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
417  dst_ptr = dst_row_ptr[dst_blk_x];
418  src_ptr = src_row_ptr[dst_blk_x];
419  for (i = 0; i < DCTSIZE; i += 2) {
420  for (j = 0; j < DCTSIZE; j++)
421  *dst_ptr++ = *src_ptr++;
422  for (j = 0; j < DCTSIZE; j++)
423  *dst_ptr++ = - *src_ptr++;
424  }
425  }
426  } else {
427  /* Remaining rows are just mirrored horizontally. */
428  dst_row_ptr = dst_buffer[offset_y];
429  src_row_ptr = src_buffer[offset_y];
430  /* Process the blocks that can be mirrored. */
431  for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
432  dst_ptr = dst_row_ptr[dst_blk_x];
433  src_ptr = src_row_ptr[comp_width - dst_blk_x - 1];
434  for (i = 0; i < DCTSIZE2; i += 2) {
435  *dst_ptr++ = *src_ptr++;
436  *dst_ptr++ = - *src_ptr++;
437  }
438  }
439  /* Any remaining right-edge blocks are only copied. */
440  for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
441  dst_ptr = dst_row_ptr[dst_blk_x];
442  src_ptr = src_row_ptr[dst_blk_x];
443  for (i = 0; i < DCTSIZE2; i++)
444  *dst_ptr++ = *src_ptr++;
445  }
446  }
447  }
448  }
449  }
450 }
451 
452 
453 LOCAL(void)
454 do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
455  jvirt_barray_ptr *src_coef_arrays,
456  jvirt_barray_ptr *dst_coef_arrays)
457 /* Transverse transpose is equivalent to
458  * 1. 180 degree rotation;
459  * 2. Transposition;
460  * or
461  * 1. Horizontal mirroring;
462  * 2. Transposition;
463  * 3. Horizontal mirroring.
464  * These steps are merged into a single processing routine.
465  */
466 {
467  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
468  int ci, i, j, offset_x, offset_y;
469  JBLOCKARRAY src_buffer, dst_buffer;
470  JCOEFPTR src_ptr, dst_ptr;
472 
473  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
474  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
475 
476  for (ci = 0; ci < dstinfo->num_components; ci++) {
477  compptr = dstinfo->comp_info + ci;
478  comp_width = MCU_cols * compptr->h_samp_factor;
479  comp_height = MCU_rows * compptr->v_samp_factor;
480  for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
481  dst_blk_y += compptr->v_samp_factor) {
482  dst_buffer = (*srcinfo->mem->access_virt_barray)
483  ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
484  (JDIMENSION) compptr->v_samp_factor, TRUE);
485  for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
486  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
487  dst_blk_x += compptr->h_samp_factor) {
488  src_buffer = (*srcinfo->mem->access_virt_barray)
489  ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
490  (JDIMENSION) compptr->h_samp_factor, FALSE);
491  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
492  if (dst_blk_y < comp_height) {
493  src_ptr = src_buffer[offset_x]
494  [comp_height - dst_blk_y - offset_y - 1];
495  if (dst_blk_x < comp_width) {
496  /* Block is within the mirrorable area. */
497  dst_ptr = dst_buffer[offset_y]
498  [comp_width - dst_blk_x - offset_x - 1];
499  for (i = 0; i < DCTSIZE; i++) {
500  for (j = 0; j < DCTSIZE; j++) {
501  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
502  j++;
503  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
504  }
505  i++;
506  for (j = 0; j < DCTSIZE; j++) {
507  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
508  j++;
509  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
510  }
511  }
512  } else {
513  /* Right-edge blocks are mirrored in y only */
514  dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
515  for (i = 0; i < DCTSIZE; i++) {
516  for (j = 0; j < DCTSIZE; j++) {
517  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
518  j++;
519  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
520  }
521  }
522  }
523  } else {
524  src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
525  if (dst_blk_x < comp_width) {
526  /* Bottom-edge blocks are mirrored in x only */
527  dst_ptr = dst_buffer[offset_y]
528  [comp_width - dst_blk_x - offset_x - 1];
529  for (i = 0; i < DCTSIZE; i++) {
530  for (j = 0; j < DCTSIZE; j++)
531  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
532  i++;
533  for (j = 0; j < DCTSIZE; j++)
534  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
535  }
536  } else {
537  /* At lower right corner, just transpose, no mirroring */
538  dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
539  for (i = 0; i < DCTSIZE; i++)
540  for (j = 0; j < DCTSIZE; j++)
541  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
542  }
543  }
544  }
545  }
546  }
547  }
548  }
549 }
550 
551 
552 /* Request any required workspace.
553  *
554  * We allocate the workspace virtual arrays from the source decompression
555  * object, so that all the arrays (both the original data and the workspace)
556  * will be taken into account while making memory management decisions.
557  * Hence, this routine must be called after jpeg_read_header (which reads
558  * the image dimensions) and before jpeg_read_coefficients (which realizes
559  * the source's virtual arrays).
560  */
561 
562 GLOBAL(void)
563 jtransform_request_workspace (j_decompress_ptr srcinfo,
565 {
568  int ci;
569 
570  if (info->force_grayscale &&
571  srcinfo->jpeg_color_space == JCS_YCbCr &&
572  srcinfo->num_components == 3) {
573  /* We'll only process the first component */
574  info->num_components = 1;
575  } else {
576  /* Process all the components */
577  info->num_components = srcinfo->num_components;
578  }
579 
580  switch (info->transform) {
581  case JXFORM_NONE:
582  case JXFORM_FLIP_H:
583  /* Don't need a workspace array */
584  break;
585  case JXFORM_FLIP_V:
586  case JXFORM_ROT_180:
587  /* Need workspace arrays having same dimensions as source image.
588  * Note that we allocate arrays padded out to the next iMCU boundary,
589  * so that transform routines need not worry about missing edge blocks.
590  */
591  coef_arrays = (jvirt_barray_ptr *)
592  (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
593  SIZEOF(jvirt_barray_ptr) * info->num_components);
594  for (ci = 0; ci < info->num_components; ci++) {
595  compptr = srcinfo->comp_info + ci;
596  coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
597  ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
598  (JDIMENSION) jround_up((long) compptr->width_in_blocks,
599  (long) compptr->h_samp_factor),
600  (JDIMENSION) jround_up((long) compptr->height_in_blocks,
601  (long) compptr->v_samp_factor),
602  (JDIMENSION) compptr->v_samp_factor);
603  }
604  break;
605  case JXFORM_TRANSPOSE:
606  case JXFORM_TRANSVERSE:
607  case JXFORM_ROT_90:
608  case JXFORM_ROT_270:
609  /* Need workspace arrays having transposed dimensions.
610  * Note that we allocate arrays padded out to the next iMCU boundary,
611  * so that transform routines need not worry about missing edge blocks.
612  */
613  coef_arrays = (jvirt_barray_ptr *)
614  (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
615  SIZEOF(jvirt_barray_ptr) * info->num_components);
616  for (ci = 0; ci < info->num_components; ci++) {
617  compptr = srcinfo->comp_info + ci;
618  coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
619  ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
620  (JDIMENSION) jround_up((long) compptr->height_in_blocks,
621  (long) compptr->v_samp_factor),
622  (JDIMENSION) jround_up((long) compptr->width_in_blocks,
623  (long) compptr->h_samp_factor),
624  (JDIMENSION) compptr->h_samp_factor);
625  }
626  break;
627  }
628  info->workspace_coef_arrays = coef_arrays;
629 }
630 
631 
632 /* Transpose destination image parameters */
633 
634 LOCAL(void)
635 transpose_critical_parameters (j_compress_ptr dstinfo)
636 {
637  int tblno, i, j, ci, itemp;
639  JQUANT_TBL *qtblptr;
640  JDIMENSION dtemp;
641  UINT16 qtemp;
642 
643  /* Transpose basic image dimensions */
644  dtemp = dstinfo->image_width;
645  dstinfo->image_width = dstinfo->image_height;
646  dstinfo->image_height = dtemp;
647 
648  /* Transpose sampling factors */
649  for (ci = 0; ci < dstinfo->num_components; ci++) {
650  compptr = dstinfo->comp_info + ci;
651  itemp = compptr->h_samp_factor;
652  compptr->h_samp_factor = compptr->v_samp_factor;
653  compptr->v_samp_factor = itemp;
654  }
655 
656  /* Transpose quantization tables */
657  for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
658  qtblptr = dstinfo->quant_tbl_ptrs[tblno];
659  if (qtblptr != NULL) {
660  for (i = 0; i < DCTSIZE; i++) {
661  for (j = 0; j < i; j++) {
662  qtemp = qtblptr->quantval[i*DCTSIZE+j];
663  qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i];
664  qtblptr->quantval[j*DCTSIZE+i] = qtemp;
665  }
666  }
667  }
668  }
669 }
670 
671 
672 /* Trim off any partial iMCUs on the indicated destination edge */
673 
674 LOCAL(void)
675 trim_right_edge (j_compress_ptr dstinfo)
676 {
677  int ci, max_h_samp_factor;
678  JDIMENSION MCU_cols;
679 
680  /* We have to compute max_h_samp_factor ourselves,
681  * because it hasn't been set yet in the destination
682  * (and we don't want to use the source's value).
683  */
684  max_h_samp_factor = 1;
685  for (ci = 0; ci < dstinfo->num_components; ci++) {
686  int h_samp_factor = dstinfo->comp_info[ci].h_samp_factor;
687  max_h_samp_factor = MAX(max_h_samp_factor, h_samp_factor);
688  }
689  MCU_cols = dstinfo->image_width / (max_h_samp_factor * DCTSIZE);
690  if (MCU_cols > 0) /* can't trim to 0 pixels */
691  dstinfo->image_width = MCU_cols * (max_h_samp_factor * DCTSIZE);
692 }
693 
694 LOCAL(void)
695 trim_bottom_edge (j_compress_ptr dstinfo)
696 {
697  int ci, max_v_samp_factor;
698  JDIMENSION MCU_rows;
699 
700  /* We have to compute max_v_samp_factor ourselves,
701  * because it hasn't been set yet in the destination
702  * (and we don't want to use the source's value).
703  */
704  max_v_samp_factor = 1;
705  for (ci = 0; ci < dstinfo->num_components; ci++) {
706  int v_samp_factor = dstinfo->comp_info[ci].v_samp_factor;
707  max_v_samp_factor = MAX(max_v_samp_factor, v_samp_factor);
708  }
709  MCU_rows = dstinfo->image_height / (max_v_samp_factor * DCTSIZE);
710  if (MCU_rows > 0) /* can't trim to 0 pixels */
711  dstinfo->image_height = MCU_rows * (max_v_samp_factor * DCTSIZE);
712 }
713 
714 
715 /* Adjust output image parameters as needed.
716  *
717  * This must be called after jpeg_copy_critical_parameters()
718  * and before jpeg_write_coefficients().
719  *
720  * The return value is the set of virtual coefficient arrays to be written
721  * (either the ones allocated by jtransform_request_workspace, or the
722  * original source data arrays). The caller will need to pass this value
723  * to jpeg_write_coefficients().
724  */
725 
727 jtransform_adjust_parameters (j_decompress_ptr ,
728  j_compress_ptr dstinfo,
729  jvirt_barray_ptr *src_coef_arrays,
730  jpeg_transform_info *info)
731 {
732  /* If force-to-grayscale is requested, adjust destination parameters */
733  if (info->force_grayscale) {
734  /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed
735  * properly. Among other things, the target h_samp_factor & v_samp_factor
736  * will get set to 1, which typically won't match the source.
737  * In fact we do this even if the source is already grayscale; that
738  * provides an easy way of coercing a grayscale JPEG with funny sampling
739  * factors to the customary 1,1. (Some decoders fail on other factors.)
740  */
741  if ((dstinfo->jpeg_color_space == JCS_YCbCr &&
742  dstinfo->num_components == 3) ||
743  (dstinfo->jpeg_color_space == JCS_GRAYSCALE &&
744  dstinfo->num_components == 1)) {
745  /* We have to preserve the source's quantization table number. */
746  int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no;
748  dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no;
749  } else {
750  /* Sorry, can't do it */
751  ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL);
752  }
753  }
754 
755  /* Correct the destination's image dimensions etc if necessary */
756  switch (info->transform) {
757  case JXFORM_NONE:
758  /* Nothing to do */
759  break;
760  case JXFORM_FLIP_H:
761  if (info->trim)
762  trim_right_edge(dstinfo);
763  break;
764  case JXFORM_FLIP_V:
765  if (info->trim)
766  trim_bottom_edge(dstinfo);
767  break;
768  case JXFORM_TRANSPOSE:
769  transpose_critical_parameters(dstinfo);
770  /* transpose does NOT have to trim anything */
771  break;
772  case JXFORM_TRANSVERSE:
773  transpose_critical_parameters(dstinfo);
774  if (info->trim) {
775  trim_right_edge(dstinfo);
776  trim_bottom_edge(dstinfo);
777  }
778  break;
779  case JXFORM_ROT_90:
780  transpose_critical_parameters(dstinfo);
781  if (info->trim)
782  trim_right_edge(dstinfo);
783  break;
784  case JXFORM_ROT_180:
785  if (info->trim) {
786  trim_right_edge(dstinfo);
787  trim_bottom_edge(dstinfo);
788  }
789  break;
790  case JXFORM_ROT_270:
791  transpose_critical_parameters(dstinfo);
792  if (info->trim)
793  trim_bottom_edge(dstinfo);
794  break;
795  }
796 
797  /* Return the appropriate output data set */
798  if (info->workspace_coef_arrays != NULL)
799  return info->workspace_coef_arrays;
800  return src_coef_arrays;
801 }
802 
803 
804 /* Execute the actual transformation, if any.
805  *
806  * This must be called *after* jpeg_write_coefficients, because it depends
807  * on jpeg_write_coefficients to have computed subsidiary values such as
808  * the per-component width and height fields in the destination object.
809  *
810  * Note that some transformations will modify the source data arrays!
811  */
812 
813 GLOBAL(void)
814 jtransform_execute_transformation (j_decompress_ptr srcinfo,
815  j_compress_ptr dstinfo,
816  jvirt_barray_ptr *src_coef_arrays,
817  jpeg_transform_info *info)
818 {
819  jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays;
820 
821  switch (info->transform) {
822  case JXFORM_NONE:
823  break;
824  case JXFORM_FLIP_H:
825  do_flip_h(srcinfo, dstinfo, src_coef_arrays);
826  break;
827  case JXFORM_FLIP_V:
828  do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
829  break;
830  case JXFORM_TRANSPOSE:
831  do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
832  break;
833  case JXFORM_TRANSVERSE:
834  do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
835  break;
836  case JXFORM_ROT_90:
837  do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
838  break;
839  case JXFORM_ROT_180:
840  do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
841  break;
842  case JXFORM_ROT_270:
843  do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
844  break;
845  }
846 }
847 
848 #endif /* TRANSFORMS_SUPPORTED */
849 
850 
851 /* Setup decompression object to save desired markers in memory.
852  * This must be called before jpeg_read_header() to have the desired effect.
853  */
854 
855 GLOBAL(void)
856 jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option)
857 {
858 #ifdef SAVE_MARKERS_SUPPORTED
859  int m;
860 
861  /* Save comments except under NONE option */
862  if (option != JCOPYOPT_NONE) {
863  jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF);
864  }
865  /* Save all types of APPn markers iff ALL option */
866  if (option == JCOPYOPT_ALL) {
867  for (m = 0; m < 16; m++)
868  jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF);
869  }
870 #endif /* SAVE_MARKERS_SUPPORTED */
871 }
872 
873 /* Copy markers saved in the given source object to the destination object.
874  * This should be called just after jpeg_start_compress() or
875  * jpeg_write_coefficients().
876  * Note that those routines will have written the SOI, and also the
877  * JFIF APP0 or Adobe APP14 markers if selected.
878  */
879 
880 GLOBAL(void)
881 jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
882  JCOPY_OPTION )
883 {
885 
886  /* In the current implementation, we don't actually need to examine the
887  * option flag here; we just copy everything that got saved.
888  * But to avoid confusion, we do not output JFIF and Adobe APP14 markers
889  * if the encoder library already wrote one.
890  */
891  for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) {
892  if (dstinfo->write_JFIF_header &&
893  marker->marker == JPEG_APP0 &&
894  marker->data_length >= 5 &&
895  GETJOCTET(marker->data[0]) == 0x4A &&
896  GETJOCTET(marker->data[1]) == 0x46 &&
897  GETJOCTET(marker->data[2]) == 0x49 &&
898  GETJOCTET(marker->data[3]) == 0x46 &&
899  GETJOCTET(marker->data[4]) == 0)
900  continue; /* reject duplicate JFIF */
901  if (dstinfo->write_Adobe_marker &&
902  marker->marker == JPEG_APP0+14 &&
903  marker->data_length >= 5 &&
904  GETJOCTET(marker->data[0]) == 0x41 &&
905  GETJOCTET(marker->data[1]) == 0x64 &&
906  GETJOCTET(marker->data[2]) == 0x6F &&
907  GETJOCTET(marker->data[3]) == 0x62 &&
908  GETJOCTET(marker->data[4]) == 0x65)
909  continue; /* reject duplicate Adobe */
910 #ifdef NEED_FAR_POINTERS
911  /* We could use jpeg_write_marker if the data weren't FAR... */
912  {
913  unsigned int i;
914  jpeg_write_m_header(dstinfo, marker->marker, marker->data_length);
915  for (i = 0; i < marker->data_length; i++)
916  jpeg_write_m_byte(dstinfo, marker->data[i]);
917  }
918 #else
919  jpeg_write_marker(dstinfo, marker->marker,
920  marker->data, marker->data_length);
921 #endif
922  }
923 }
UINT16 quantval[DCTSIZE2]
Definition: mrpt_jpeglib.h:85
jcopy_block_row(JBLOCKROW input_row, JBLOCKROW output_row, JDIMENSION num_blocks)
Definition: jutils.cpp:141
#define GETJOCTET(value)
Definition: jmorecfg.h:116
#define DCTSIZE
Definition: mrpt_jpeglib.h:38
jround_up(long a, long b)
Definition: jutils.cpp:77
struct jpeg_common_struct * j_common_ptr
Definition: mrpt_jpeglib.h:258
#define ERREXIT(cinfo, code)
Definition: jerror.h:199
#define SIZEOF(object)
Definition: jinclude.h:73
struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr
Definition: mrpt_jpeglib.h:190
short JCOEF
Definition: jmorecfg.h:96
JCOPY_OPTION option
Definition: transupp.h:121
#define JPEG_APP0
jpeg_component_info * compptr
Definition: jdct.h:97
jvirt_barray_ptr * coef_arrays
Definition: jctrans.cpp:17
JDIMENSION width_in_blocks
Definition: mrpt_jpeglib.h:136
int marker
Definition: mrpt_jpeglib.h:947
jpeg_write_m_byte(j_compress_ptr cinfo, int val)
Definition: jcapimin.cpp:217
JDIMENSION height_in_blocks
Definition: mrpt_jpeglib.h:137
jpeg_set_colorspace(j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
Definition: jcparam.cpp:388
#define FALSE
Definition: jmorecfg.h:227
#define MAX(a, b)
Definition: jpegint.h:264
#define JPOOL_IMAGE
Definition: mrpt_jpeglib.h:746
#define LOCAL(type)
Definition: jmorecfg.h:183
#define JPEG_COM
JCOEF FAR * JCOEFPTR
Definition: mrpt_jpeglib.h:72
GLuint buffer
Definition: glew.h:1585
#define DCTSIZE2
Definition: mrpt_jpeglib.h:39
#define TRUE
Definition: jmorecfg.h:230
unsigned int UINT16
Definition: jmorecfg.h:146
jpeg_write_m_header(j_compress_ptr cinfo, int marker, unsigned int datalen)
Definition: jcapimin.cpp:205
jpeg_write_marker(j_compress_ptr cinfo, int marker, const JOCTET *dataptr, unsigned int datalen)
Definition: jcapimin.cpp:183
jpeg_save_markers(j_decompress_ptr cinfo, int marker_code, unsigned int length_limit)
Definition: jdmarker.cpp:1295
j_compress_ptr dstinfo
JBLOCKROW * JBLOCKARRAY
Definition: mrpt_jpeglib.h:69
#define GLOBAL(type)
Definition: jmorecfg.h:185
backing_store_ptr info
Definition: jmemsys.h:170
#define NUM_QUANT_TBLS
Definition: mrpt_jpeglib.h:40
jcopy_markers_setup(j_decompress_ptr srcinfo, JCOPY_OPTION option)
Definition: transupp.cpp:856
const GLdouble * m
Definition: glew.h:5094
JBLOCK FAR * JBLOCKROW
Definition: mrpt_jpeglib.h:68
unsigned int JDIMENSION
Definition: jmorecfg.h:168
boolean int tblno
Definition: jchuff.h:39
JCOPY_OPTION
Definition: transupp.h:111
jcopy_markers_execute(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, JCOPY_OPTION)
Definition: transupp.cpp:881



Page generated by Doxygen 1.8.6 for MRPT 1.5.6 Git: 4c65e84 Tue Apr 24 08:18:17 2018 +0200 at mar abr 24 08:26:17 CEST 2018