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



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019