LibreOffice Module vcl (master)  1
transupp.c
Go to the documentation of this file.
1 /*
2  * transupp.c
3  *
4  * This file was part of the Independent JPEG Group's software:
5  * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding.
6  * Modifications:
7  * Copyright (C) 2010, D. R. Commander.
8  * For conditions of distribution and use, see the accompanying README file.
9  *
10  * This file contains image transformation routines and other utility code
11  * used by the jpegtran sample application. These are NOT part of the core
12  * JPEG library. But we keep these routines separate from jpegtran.c to
13  * ease the task of maintaining jpegtran-like programs that have other user
14  * interfaces.
15  */
16 
17 #include <sal/config.h>
18 
19 #include "jinclude.h"
20 #include <jerror.h>
21 #include <jpeglib.h>
22 #include "transupp.h" /* My own external interface */
23 #include "jpegcomp.h"
24 
25 /* Definition of jdiv_round_up is copied here from jutils.c in jpeg-8c.tar.gz,
26  just as the rest of this file appears to be copied here from transupp.c in
27  jpeg-8c.tar.gz: */
28 static long
29 jdiv_round_up (long a, long b)
30 /* Compute a/b rounded up to next integer, ie, ceil(a/b) */
31 /* Assumes a >= 0, b > 0 */
32 {
33  return (a + b - 1) / b;
34 }
35 
36 #if JPEG_LIB_VERSION >= 70
37 #define dstinfo_min_DCT_h_scaled_size dstinfo->min_DCT_h_scaled_size
38 #define dstinfo_min_DCT_v_scaled_size dstinfo->min_DCT_v_scaled_size
39 #else
40 #define dstinfo_min_DCT_h_scaled_size DCTSIZE
41 #define dstinfo_min_DCT_v_scaled_size DCTSIZE
42 #endif
43 
44 
45 #if TRANSFORMS_SUPPORTED
46 
47 /*
48  * Lossless image transformation routines. These routines work on DCT
49  * coefficient arrays and thus do not require any lossy decompression
50  * or recompression of the image.
51  * Thanks to Guido Vollbeding for the initial design and code of this feature,
52  * and to Ben Jackson for introducing the cropping feature.
53  *
54  * Horizontal flipping is done in-place, using a single top-to-bottom
55  * pass through the virtual source array. It will thus be much the
56  * fastest option for images larger than main memory.
57  *
58  * The other routines require a set of destination virtual arrays, so they
59  * need twice as much memory as jpegtran normally does. The destination
60  * arrays are always written in normal scan order (top to bottom) because
61  * the virtual array manager expects this. The source arrays will be scanned
62  * in the corresponding order, which means multiple passes through the source
63  * arrays for most of the transforms. That could result in much thrashing
64  * if the image is larger than main memory.
65  *
66  * If cropping or trimming is involved, the destination arrays may be smaller
67  * than the source arrays. Note it is not possible to do horizontal flip
68  * in-place when a nonzero Y crop offset is specified, since we'd have to move
69  * data from one block row to another but the virtual array manager doesn't
70  * guarantee we can touch more than one row at a time. So in that case,
71  * we have to use a separate destination array.
72  *
73  * Some notes about the operating environment of the individual transform
74  * routines:
75  * 1. Both the source and destination virtual arrays are allocated from the
76  * source JPEG object, and therefore should be manipulated by calling the
77  * source's memory manager.
78  * 2. The destination's component count should be used. It may be smaller
79  * than the source's when forcing to grayscale.
80  * 3. Likewise the destination's sampling factors should be used. When
81  * forcing to grayscale the destination's sampling factors will be all 1,
82  * and we may as well take that as the effective iMCU size.
83  * 4. When "trim" is in effect, the destination's dimensions will be the
84  * trimmed values but the source's will be untrimmed.
85  * 5. When "crop" is in effect, the destination's dimensions will be the
86  * cropped values but the source's will be uncropped. Each transform
87  * routine is responsible for picking up source data starting at the
88  * correct X and Y offset for the crop region. (The X and Y offsets
89  * passed to the transform routines are measured in iMCU blocks of the
90  * destination.)
91  * 6. All the routines assume that the source and destination buffers are
92  * padded out to a full iMCU boundary. This is true, although for the
93  * source buffer it is an undocumented property of jdcoefct.c.
94  */
95 
96 static void lcl_jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row, JDIMENSION num_blocks)
97 /* Copy a row of coefficient blocks from one place to another. */
98 {
99 #ifdef FMEMCOPY
100  FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
101 #else
102  JCOEFPTR inptr, outptr;
103  long count;
104 
105  inptr = (JCOEFPTR) input_row;
106  outptr = (JCOEFPTR) output_row;
107  for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) {
108  *outptr++ = *inptr++;
109  }
110 #endif
111 }
112 
113 LOCAL(void)
114 do_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
115  JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
116  jvirt_barray_ptr *src_coef_arrays,
117  jvirt_barray_ptr *dst_coef_arrays)
118 /* Crop. This is only used when no rotate/flip is requested with the crop. */
119 {
120  JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks;
121  int ci, offset_y;
122  JBLOCKARRAY src_buffer, dst_buffer;
123  jpeg_component_info *compptr;
124 
125  /* We simply have to copy the right amount of data (the destination's
126  * image size) starting at the given X and Y offsets in the source.
127  */
128  for (ci = 0; ci < dstinfo->num_components; ci++) {
129  compptr = dstinfo->comp_info + ci;
130  x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
131  y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
132  for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
133  dst_blk_y += compptr->v_samp_factor) {
134  dst_buffer = (*srcinfo->mem->access_virt_barray)
135  ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
136  (JDIMENSION) compptr->v_samp_factor, TRUE);
137  src_buffer = (*srcinfo->mem->access_virt_barray)
138  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
139  dst_blk_y + y_crop_blocks,
140  (JDIMENSION) compptr->v_samp_factor, FALSE);
141  for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
142  lcl_jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
143  dst_buffer[offset_y],
144  compptr->width_in_blocks);
145  }
146  }
147  }
148 }
149 
150 
151 LOCAL(void)
152 do_flip_h_no_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
153  JDIMENSION x_crop_offset,
154  jvirt_barray_ptr *src_coef_arrays)
155 /* Horizontal flip; done in-place, so no separate dest array is required.
156  * NB: this only works when y_crop_offset is zero.
157  */
158 {
159  JDIMENSION MCU_cols, comp_width, blk_x, blk_y, x_crop_blocks;
160  int ci, k, offset_y;
161  JBLOCKARRAY buffer;
162  JCOEFPTR ptr1, ptr2;
163  JCOEF temp1, temp2;
164  jpeg_component_info *compptr;
165 
166  /* Horizontal mirroring of DCT blocks is accomplished by swapping
167  * pairs of blocks in-place. Within a DCT block, we perform horizontal
168  * mirroring by changing the signs of odd-numbered columns.
169  * Partial iMCUs at the right edge are left untouched.
170  */
171  MCU_cols = srcinfo->output_width /
172  (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
173 
174  for (ci = 0; ci < dstinfo->num_components; ci++) {
175  compptr = dstinfo->comp_info + ci;
176  comp_width = MCU_cols * compptr->h_samp_factor;
177  x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
178  for (blk_y = 0; blk_y < compptr->height_in_blocks;
179  blk_y += compptr->v_samp_factor) {
180  buffer = (*srcinfo->mem->access_virt_barray)
181  ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y,
182  (JDIMENSION) compptr->v_samp_factor, TRUE);
183  for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
184  /* Do the mirroring */
185  for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) {
186  ptr1 = buffer[offset_y][blk_x];
187  ptr2 = buffer[offset_y][comp_width - blk_x - 1];
188  /* this unrolled loop doesn't need to know which row it's on... */
189  for (k = 0; k < DCTSIZE2; k += 2) {
190  temp1 = *ptr1; /* swap even column */
191  temp2 = *ptr2;
192  *ptr1++ = temp2;
193  *ptr2++ = temp1;
194  temp1 = *ptr1; /* swap odd column with sign change */
195  temp2 = *ptr2;
196  *ptr1++ = -temp2;
197  *ptr2++ = -temp1;
198  }
199  }
200  if (x_crop_blocks > 0) {
201  /* Now left-justify the portion of the data to be kept.
202  * We can't use a single lcl_jcopy_block_row() call because that routine
203  * depends on memcpy(), whose behavior is unspecified for overlapping
204  * source and destination areas. Sigh.
205  */
206  for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) {
207  lcl_jcopy_block_row(buffer[offset_y] + blk_x + x_crop_blocks,
208  buffer[offset_y] + blk_x,
209  (JDIMENSION) 1);
210  }
211  }
212  }
213  }
214  }
215 }
216 
217 
218 LOCAL(void)
219 do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
220  JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
221  jvirt_barray_ptr *src_coef_arrays,
222  jvirt_barray_ptr *dst_coef_arrays)
223 /* Horizontal flip in general cropping case */
224 {
225  JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
226  JDIMENSION x_crop_blocks, y_crop_blocks;
227  int ci, k, offset_y;
228  JBLOCKARRAY src_buffer, dst_buffer;
229  JBLOCKROW src_row_ptr, dst_row_ptr;
230  JCOEFPTR src_ptr, dst_ptr;
231  jpeg_component_info *compptr;
232 
233  /* Here we must output into a separate array because we can't touch
234  * different rows of a single virtual array simultaneously. Otherwise,
235  * this is essentially the same as the routine above.
236  */
237  MCU_cols = srcinfo->output_width /
238  (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
239 
240  for (ci = 0; ci < dstinfo->num_components; ci++) {
241  compptr = dstinfo->comp_info + ci;
242  comp_width = MCU_cols * compptr->h_samp_factor;
243  x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
244  y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
245  for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
246  dst_blk_y += compptr->v_samp_factor) {
247  dst_buffer = (*srcinfo->mem->access_virt_barray)
248  ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
249  (JDIMENSION) compptr->v_samp_factor, TRUE);
250  src_buffer = (*srcinfo->mem->access_virt_barray)
251  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
252  dst_blk_y + y_crop_blocks,
253  (JDIMENSION) compptr->v_samp_factor, FALSE);
254  for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
255  dst_row_ptr = dst_buffer[offset_y];
256  src_row_ptr = src_buffer[offset_y];
257  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
258  if (x_crop_blocks + dst_blk_x < comp_width) {
259  /* Do the mirrorable blocks */
260  dst_ptr = dst_row_ptr[dst_blk_x];
261  src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
262  /* this unrolled loop doesn't need to know which row it's on... */
263  for (k = 0; k < DCTSIZE2; k += 2) {
264  *dst_ptr++ = *src_ptr++; /* copy even column */
265  *dst_ptr++ = - *src_ptr++; /* copy odd column with sign change */
266  }
267  } else {
268  /* Copy last partial block(s) verbatim */
269  lcl_jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks,
270  dst_row_ptr + dst_blk_x,
271  (JDIMENSION) 1);
272  }
273  }
274  }
275  }
276  }
277 }
278 
279 
280 LOCAL(void)
281 do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
282  JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
283  jvirt_barray_ptr *src_coef_arrays,
284  jvirt_barray_ptr *dst_coef_arrays)
285 /* Vertical flip */
286 {
287  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
288  JDIMENSION x_crop_blocks, y_crop_blocks;
289  int ci, i, j, offset_y;
290  JBLOCKARRAY src_buffer, dst_buffer;
291  JBLOCKROW src_row_ptr, dst_row_ptr;
292  JCOEFPTR src_ptr, dst_ptr;
293  jpeg_component_info *compptr;
294 
295  /* We output into a separate array because we can't touch different
296  * rows of the source virtual array simultaneously. Otherwise, this
297  * is a pretty straightforward analog of horizontal flip.
298  * Within a DCT block, vertical mirroring is done by changing the signs
299  * of odd-numbered rows.
300  * Partial iMCUs at the bottom edge are copied verbatim.
301  */
302  MCU_rows = srcinfo->output_height /
303  (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
304 
305  for (ci = 0; ci < dstinfo->num_components; ci++) {
306  compptr = dstinfo->comp_info + ci;
307  comp_height = MCU_rows * compptr->v_samp_factor;
308  x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
309  y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
310  for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
311  dst_blk_y += compptr->v_samp_factor) {
312  dst_buffer = (*srcinfo->mem->access_virt_barray)
313  ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
314  (JDIMENSION) compptr->v_samp_factor, TRUE);
315  if (y_crop_blocks + dst_blk_y < comp_height) {
316  /* Row is within the mirrorable area. */
317  src_buffer = (*srcinfo->mem->access_virt_barray)
318  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
319  comp_height - y_crop_blocks - dst_blk_y -
320  (JDIMENSION) compptr->v_samp_factor,
321  (JDIMENSION) compptr->v_samp_factor, FALSE);
322  } else {
323  /* Bottom-edge blocks will be copied verbatim. */
324  src_buffer = (*srcinfo->mem->access_virt_barray)
325  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
326  dst_blk_y + y_crop_blocks,
327  (JDIMENSION) compptr->v_samp_factor, FALSE);
328  }
329  for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
330  if (y_crop_blocks + dst_blk_y < comp_height) {
331  /* Row is within the mirrorable area. */
332  dst_row_ptr = dst_buffer[offset_y];
333  src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
334  src_row_ptr += x_crop_blocks;
335  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
336  dst_blk_x++) {
337  dst_ptr = dst_row_ptr[dst_blk_x];
338  src_ptr = src_row_ptr[dst_blk_x];
339  for (i = 0; i < DCTSIZE; i += 2) {
340  /* copy even row */
341  for (j = 0; j < DCTSIZE; j++)
342  *dst_ptr++ = *src_ptr++;
343  /* copy odd row with sign change */
344  for (j = 0; j < DCTSIZE; j++)
345  *dst_ptr++ = - *src_ptr++;
346  }
347  }
348  } else {
349  /* Just copy row verbatim. */
350  lcl_jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
351  dst_buffer[offset_y],
352  compptr->width_in_blocks);
353  }
354  }
355  }
356  }
357 }
358 
359 
360 LOCAL(void)
361 do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
362  JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
363  jvirt_barray_ptr *src_coef_arrays,
364  jvirt_barray_ptr *dst_coef_arrays)
365 /* Transpose source into destination */
366 {
367  JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks;
368  int ci, i, j, offset_x, offset_y;
369  JBLOCKARRAY src_buffer, dst_buffer;
370  JCOEFPTR src_ptr, dst_ptr;
371  jpeg_component_info *compptr;
372 
373  /* Transposing pixels within a block just requires transposing the
374  * DCT coefficients.
375  * Partial iMCUs at the edges require no special treatment; we simply
376  * process all the available DCT blocks for every component.
377  */
378  for (ci = 0; ci < dstinfo->num_components; ci++) {
379  compptr = dstinfo->comp_info + ci;
380  x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
381  y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
382  for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
383  dst_blk_y += compptr->v_samp_factor) {
384  dst_buffer = (*srcinfo->mem->access_virt_barray)
385  ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
386  (JDIMENSION) compptr->v_samp_factor, TRUE);
387  for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
388  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
389  dst_blk_x += compptr->h_samp_factor) {
390  src_buffer = (*srcinfo->mem->access_virt_barray)
391  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
392  dst_blk_x + x_crop_blocks,
393  (JDIMENSION) compptr->h_samp_factor, FALSE);
394  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
395  dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
396  src_ptr = src_buffer[offset_x][dst_blk_y + offset_y + y_crop_blocks];
397  for (i = 0; i < DCTSIZE; i++)
398  for (j = 0; j < DCTSIZE; j++)
399  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
400  }
401  }
402  }
403  }
404  }
405 }
406 
407 
408 LOCAL(void)
409 do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
410  JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
411  jvirt_barray_ptr *src_coef_arrays,
412  jvirt_barray_ptr *dst_coef_arrays)
413 /* 90 degree rotation is equivalent to
414  * 1. Transposing the image;
415  * 2. Horizontal mirroring.
416  * These two steps are merged into a single processing routine.
417  */
418 {
419  JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
420  JDIMENSION x_crop_blocks, y_crop_blocks;
421  int ci, i, j, offset_x, offset_y;
422  JBLOCKARRAY src_buffer, dst_buffer;
423  JCOEFPTR src_ptr, dst_ptr;
424  jpeg_component_info *compptr;
425 
426  /* Because of the horizontal mirror step, we can't process partial iMCUs
427  * at the (output) right edge properly. They just get transposed and
428  * not mirrored.
429  */
430  MCU_cols = srcinfo->output_height /
431  (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
432 
433  for (ci = 0; ci < dstinfo->num_components; ci++) {
434  compptr = dstinfo->comp_info + ci;
435  comp_width = MCU_cols * compptr->h_samp_factor;
436  x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
437  y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
438  for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
439  dst_blk_y += compptr->v_samp_factor) {
440  dst_buffer = (*srcinfo->mem->access_virt_barray)
441  ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
442  (JDIMENSION) compptr->v_samp_factor, TRUE);
443  for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
444  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
445  dst_blk_x += compptr->h_samp_factor) {
446  if (x_crop_blocks + dst_blk_x < comp_width) {
447  /* Block is within the mirrorable area. */
448  src_buffer = (*srcinfo->mem->access_virt_barray)
449  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
450  comp_width - x_crop_blocks - dst_blk_x -
451  (JDIMENSION) compptr->h_samp_factor,
452  (JDIMENSION) compptr->h_samp_factor, FALSE);
453  } else {
454  /* Edge blocks are transposed but not mirrored. */
455  src_buffer = (*srcinfo->mem->access_virt_barray)
456  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
457  dst_blk_x + x_crop_blocks,
458  (JDIMENSION) compptr->h_samp_factor, FALSE);
459  }
460  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
461  dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
462  if (x_crop_blocks + dst_blk_x < comp_width) {
463  /* Block is within the mirrorable area. */
464  src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
465  [dst_blk_y + offset_y + y_crop_blocks];
466  for (i = 0; i < DCTSIZE; i++) {
467  for (j = 0; j < DCTSIZE; j++)
468  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
469  i++;
470  for (j = 0; j < DCTSIZE; j++)
471  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
472  }
473  } else {
474  /* Edge blocks are transposed but not mirrored. */
475  src_ptr = src_buffer[offset_x]
476  [dst_blk_y + offset_y + y_crop_blocks];
477  for (i = 0; i < DCTSIZE; i++)
478  for (j = 0; j < DCTSIZE; j++)
479  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
480  }
481  }
482  }
483  }
484  }
485  }
486 }
487 
488 
489 LOCAL(void)
490 do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
491  JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
492  jvirt_barray_ptr *src_coef_arrays,
493  jvirt_barray_ptr *dst_coef_arrays)
494 /* 270 degree rotation is equivalent to
495  * 1. Horizontal mirroring;
496  * 2. Transposing the image.
497  * These two steps are merged into a single processing routine.
498  */
499 {
500  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
501  JDIMENSION x_crop_blocks, y_crop_blocks;
502  int ci, i, j, offset_x, offset_y;
503  JBLOCKARRAY src_buffer, dst_buffer;
504  JCOEFPTR src_ptr, dst_ptr;
505  jpeg_component_info *compptr;
506 
507  /* Because of the horizontal mirror step, we can't process partial iMCUs
508  * at the (output) bottom edge properly. They just get transposed and
509  * not mirrored.
510  */
511  MCU_rows = srcinfo->output_width /
512  (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
513 
514  for (ci = 0; ci < dstinfo->num_components; ci++) {
515  compptr = dstinfo->comp_info + ci;
516  comp_height = MCU_rows * compptr->v_samp_factor;
517  x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
518  y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
519  for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
520  dst_blk_y += compptr->v_samp_factor) {
521  dst_buffer = (*srcinfo->mem->access_virt_barray)
522  ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
523  (JDIMENSION) compptr->v_samp_factor, TRUE);
524  for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
525  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
526  dst_blk_x += compptr->h_samp_factor) {
527  src_buffer = (*srcinfo->mem->access_virt_barray)
528  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
529  dst_blk_x + x_crop_blocks,
530  (JDIMENSION) compptr->h_samp_factor, FALSE);
531  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
532  dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
533  if (y_crop_blocks + dst_blk_y < comp_height) {
534  /* Block is within the mirrorable area. */
535  src_ptr = src_buffer[offset_x]
536  [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
537  for (i = 0; i < DCTSIZE; i++) {
538  for (j = 0; j < DCTSIZE; j++) {
539  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
540  j++;
541  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
542  }
543  }
544  } else {
545  /* Edge blocks are transposed but not mirrored. */
546  src_ptr = src_buffer[offset_x]
547  [dst_blk_y + offset_y + y_crop_blocks];
548  for (i = 0; i < DCTSIZE; i++)
549  for (j = 0; j < DCTSIZE; j++)
550  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
551  }
552  }
553  }
554  }
555  }
556  }
557 }
558 
559 
560 LOCAL(void)
561 do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
562  JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
563  jvirt_barray_ptr *src_coef_arrays,
564  jvirt_barray_ptr *dst_coef_arrays)
565 /* 180 degree rotation is equivalent to
566  * 1. Vertical mirroring;
567  * 2. Horizontal mirroring.
568  * These two steps are merged into a single processing routine.
569  */
570 {
571  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
572  JDIMENSION x_crop_blocks, y_crop_blocks;
573  int ci, i, j, offset_y;
574  JBLOCKARRAY src_buffer, dst_buffer;
575  JBLOCKROW src_row_ptr, dst_row_ptr;
576  JCOEFPTR src_ptr, dst_ptr;
577  jpeg_component_info *compptr;
578 
579  MCU_cols = srcinfo->output_width /
580  (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
581  MCU_rows = srcinfo->output_height /
582  (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
583 
584  for (ci = 0; ci < dstinfo->num_components; ci++) {
585  compptr = dstinfo->comp_info + ci;
586  comp_width = MCU_cols * compptr->h_samp_factor;
587  comp_height = MCU_rows * compptr->v_samp_factor;
588  x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
589  y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
590  for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
591  dst_blk_y += compptr->v_samp_factor) {
592  dst_buffer = (*srcinfo->mem->access_virt_barray)
593  ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
594  (JDIMENSION) compptr->v_samp_factor, TRUE);
595  if (y_crop_blocks + dst_blk_y < comp_height) {
596  /* Row is within the vertically mirrorable area. */
597  src_buffer = (*srcinfo->mem->access_virt_barray)
598  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
599  comp_height - y_crop_blocks - dst_blk_y -
600  (JDIMENSION) compptr->v_samp_factor,
601  (JDIMENSION) compptr->v_samp_factor, FALSE);
602  } else {
603  /* Bottom-edge rows are only mirrored horizontally. */
604  src_buffer = (*srcinfo->mem->access_virt_barray)
605  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
606  dst_blk_y + y_crop_blocks,
607  (JDIMENSION) compptr->v_samp_factor, FALSE);
608  }
609  for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
610  dst_row_ptr = dst_buffer[offset_y];
611  if (y_crop_blocks + dst_blk_y < comp_height) {
612  /* Row is within the mirrorable area. */
613  src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
614  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
615  dst_ptr = dst_row_ptr[dst_blk_x];
616  if (x_crop_blocks + dst_blk_x < comp_width) {
617  /* Process the blocks that can be mirrored both ways. */
618  src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
619  for (i = 0; i < DCTSIZE; i += 2) {
620  /* For even row, negate every odd column. */
621  for (j = 0; j < DCTSIZE; j += 2) {
622  *dst_ptr++ = *src_ptr++;
623  *dst_ptr++ = - *src_ptr++;
624  }
625  /* For odd row, negate every even column. */
626  for (j = 0; j < DCTSIZE; j += 2) {
627  *dst_ptr++ = - *src_ptr++;
628  *dst_ptr++ = *src_ptr++;
629  }
630  }
631  } else {
632  /* Any remaining right-edge blocks are only mirrored vertically. */
633  src_ptr = src_row_ptr[x_crop_blocks + dst_blk_x];
634  for (i = 0; i < DCTSIZE; i += 2) {
635  for (j = 0; j < DCTSIZE; j++)
636  *dst_ptr++ = *src_ptr++;
637  for (j = 0; j < DCTSIZE; j++)
638  *dst_ptr++ = - *src_ptr++;
639  }
640  }
641  }
642  } else {
643  /* Remaining rows are just mirrored horizontally. */
644  src_row_ptr = src_buffer[offset_y];
645  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
646  if (x_crop_blocks + dst_blk_x < comp_width) {
647  /* Process the blocks that can be mirrored. */
648  dst_ptr = dst_row_ptr[dst_blk_x];
649  src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
650  for (i = 0; i < DCTSIZE2; i += 2) {
651  *dst_ptr++ = *src_ptr++;
652  *dst_ptr++ = - *src_ptr++;
653  }
654  } else {
655  /* Any remaining right-edge blocks are only copied. */
656  lcl_jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks,
657  dst_row_ptr + dst_blk_x,
658  (JDIMENSION) 1);
659  }
660  }
661  }
662  }
663  }
664  }
665 }
666 
667 
668 LOCAL(void)
669 do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
670  JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
671  jvirt_barray_ptr *src_coef_arrays,
672  jvirt_barray_ptr *dst_coef_arrays)
673 /* Transverse transpose is equivalent to
674  * 1. 180 degree rotation;
675  * 2. Transposition;
676  * or
677  * 1. Horizontal mirroring;
678  * 2. Transposition;
679  * 3. Horizontal mirroring.
680  * These steps are merged into a single processing routine.
681  */
682 {
683  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
684  JDIMENSION x_crop_blocks, y_crop_blocks;
685  int ci, i, j, offset_x, offset_y;
686  JBLOCKARRAY src_buffer, dst_buffer;
687  JCOEFPTR src_ptr, dst_ptr;
688  jpeg_component_info *compptr;
689 
690  MCU_cols = srcinfo->output_height /
691  (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
692  MCU_rows = srcinfo->output_width /
693  (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
694 
695  for (ci = 0; ci < dstinfo->num_components; ci++) {
696  compptr = dstinfo->comp_info + ci;
697  comp_width = MCU_cols * compptr->h_samp_factor;
698  comp_height = MCU_rows * compptr->v_samp_factor;
699  x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
700  y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
701  for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
702  dst_blk_y += compptr->v_samp_factor) {
703  dst_buffer = (*srcinfo->mem->access_virt_barray)
704  ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
705  (JDIMENSION) compptr->v_samp_factor, TRUE);
706  for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
707  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
708  dst_blk_x += compptr->h_samp_factor) {
709  if (x_crop_blocks + dst_blk_x < comp_width) {
710  /* Block is within the mirrorable area. */
711  src_buffer = (*srcinfo->mem->access_virt_barray)
712  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
713  comp_width - x_crop_blocks - dst_blk_x -
714  (JDIMENSION) compptr->h_samp_factor,
715  (JDIMENSION) compptr->h_samp_factor, FALSE);
716  } else {
717  src_buffer = (*srcinfo->mem->access_virt_barray)
718  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
719  dst_blk_x + x_crop_blocks,
720  (JDIMENSION) compptr->h_samp_factor, FALSE);
721  }
722  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
723  dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
724  if (y_crop_blocks + dst_blk_y < comp_height) {
725  if (x_crop_blocks + dst_blk_x < comp_width) {
726  /* Block is within the mirrorable area. */
727  src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
728  [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
729  for (i = 0; i < DCTSIZE; i++) {
730  for (j = 0; j < DCTSIZE; j++) {
731  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
732  j++;
733  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
734  }
735  i++;
736  for (j = 0; j < DCTSIZE; j++) {
737  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
738  j++;
739  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
740  }
741  }
742  } else {
743  /* Right-edge blocks are mirrored in y only */
744  src_ptr = src_buffer[offset_x]
745  [comp_height - y_crop_blocks - dst_blk_y - offset_y - 1];
746  for (i = 0; i < DCTSIZE; i++) {
747  for (j = 0; j < DCTSIZE; j++) {
748  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
749  j++;
750  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
751  }
752  }
753  }
754  } else {
755  if (x_crop_blocks + dst_blk_x < comp_width) {
756  /* Bottom-edge blocks are mirrored in x only */
757  src_ptr = src_buffer[compptr->h_samp_factor - offset_x - 1]
758  [dst_blk_y + offset_y + y_crop_blocks];
759  for (i = 0; i < DCTSIZE; i++) {
760  for (j = 0; j < DCTSIZE; j++)
761  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
762  i++;
763  for (j = 0; j < DCTSIZE; j++)
764  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
765  }
766  } else {
767  /* At lower right corner, just transpose, no mirroring */
768  src_ptr = src_buffer[offset_x]
769  [dst_blk_y + offset_y + y_crop_blocks];
770  for (i = 0; i < DCTSIZE; i++)
771  for (j = 0; j < DCTSIZE; j++)
772  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
773  }
774  }
775  }
776  }
777  }
778  }
779  }
780 }
781 
782 
783 /* Trim off any partial iMCUs on the indicated destination edge */
784 
785 LOCAL(void)
786 trim_right_edge (jpeg_transform_info *info, JDIMENSION full_width)
787 {
788  JDIMENSION MCU_cols;
789 
790  MCU_cols = info->output_width / info->iMCU_sample_width;
791  if (MCU_cols > 0 && info->x_crop_offset + MCU_cols ==
792  full_width / info->iMCU_sample_width)
793  info->output_width = MCU_cols * info->iMCU_sample_width;
794 }
795 
796 LOCAL(void)
797 trim_bottom_edge (jpeg_transform_info *info, JDIMENSION full_height)
798 {
799  JDIMENSION MCU_rows;
800 
801  MCU_rows = info->output_height / info->iMCU_sample_height;
802  if (MCU_rows > 0 && info->y_crop_offset + MCU_rows ==
803  full_height / info->iMCU_sample_height)
804  info->output_height = MCU_rows * info->iMCU_sample_height;
805 }
806 
807 
808 /* Request any required workspace.
809  *
810  * This routine figures out the size that the output image will be
811  * (which implies that all the transform parameters must be set before
812  * it is called).
813  *
814  * We allocate the workspace virtual arrays from the source decompression
815  * object, so that all the arrays (both the original data and the workspace)
816  * will be taken into account while making memory management decisions.
817  * Hence, this routine must be called after jpeg_read_header (which reads
818  * the image dimensions) and before jpeg_read_coefficients (which realizes
819  * the source's virtual arrays).
820  *
821  * This function returns FALSE right away if -perfect is given
822  * and transformation is not perfect. Otherwise returns TRUE.
823  */
824 
825 GLOBAL(boolean)
826 jtransform_request_workspace (j_decompress_ptr srcinfo,
827  jpeg_transform_info *info)
828 {
829  jvirt_barray_ptr *coef_arrays;
830  boolean need_workspace, transpose_it;
831  jpeg_component_info *compptr;
832  JDIMENSION xoffset, yoffset;
833  JDIMENSION width_in_iMCUs, height_in_iMCUs;
834  JDIMENSION width_in_blocks, height_in_blocks;
835  int ci, h_samp_factor, v_samp_factor;
836 
837  /* Determine number of components in output image */
838  if (info->force_grayscale &&
839  srcinfo->jpeg_color_space == JCS_YCbCr &&
840  srcinfo->num_components == 3)
841  /* We'll only process the first component */
842  info->num_components = 1;
843  else
844  /* Process all the components */
845  info->num_components = srcinfo->num_components;
846 
847  /* Compute output image dimensions and related values. */
848 #if JPEG_LIB_VERSION >= 80
849  jpeg_core_output_dimensions(srcinfo);
850 #else
851  srcinfo->output_width = srcinfo->image_width;
852  srcinfo->output_height = srcinfo->image_height;
853 #endif
854 
855  /* Return right away if -perfect is given and transformation is not perfect.
856  */
857  if (info->perfect) {
858  if (info->num_components == 1) {
859  if (!jtransform_perfect_transform(srcinfo->output_width,
860  srcinfo->output_height,
861  srcinfo->min_DCT_h_scaled_size_,
862  srcinfo->min_DCT_v_scaled_size_,
863  info->transform))
864  return FALSE;
865  } else {
866  if (!jtransform_perfect_transform(srcinfo->output_width,
867  srcinfo->output_height,
868  srcinfo->max_h_samp_factor * srcinfo->min_DCT_h_scaled_size_,
869  srcinfo->max_v_samp_factor * srcinfo->min_DCT_v_scaled_size_,
870  info->transform))
871  return FALSE;
872  }
873  }
874 
875  /* If there is only one output component, force the iMCU size to be 1;
876  * else use the source iMCU size. (This allows us to do the right thing
877  * when reducing color to grayscale, and also provides a handy way of
878  * cleaning up "funny" grayscale images whose sampling factors are not 1x1.)
879  */
880  switch (info->transform) {
881  case JXFORM_TRANSPOSE:
882  case JXFORM_TRANSVERSE:
883  case JXFORM_ROT_90:
884  case JXFORM_ROT_270:
885  info->output_width = srcinfo->output_height;
886  info->output_height = srcinfo->output_width;
887  if (info->num_components == 1) {
888  info->iMCU_sample_width = srcinfo->min_DCT_v_scaled_size_;
889  info->iMCU_sample_height = srcinfo->min_DCT_h_scaled_size_;
890  } else {
891  info->iMCU_sample_width =
892  srcinfo->max_v_samp_factor * srcinfo->min_DCT_v_scaled_size_;
893  info->iMCU_sample_height =
894  srcinfo->max_h_samp_factor * srcinfo->min_DCT_h_scaled_size_;
895  }
896  break;
897  default:
898  info->output_width = srcinfo->output_width;
899  info->output_height = srcinfo->output_height;
900  if (info->num_components == 1) {
901  info->iMCU_sample_width = srcinfo->min_DCT_h_scaled_size_;
902  info->iMCU_sample_height = srcinfo->min_DCT_v_scaled_size_;
903  } else {
904  info->iMCU_sample_width =
905  srcinfo->max_h_samp_factor * srcinfo->min_DCT_h_scaled_size_;
906  info->iMCU_sample_height =
907  srcinfo->max_v_samp_factor * srcinfo->min_DCT_v_scaled_size_;
908  }
909  break;
910  }
911 
912  /* If cropping has been requested, compute the crop area's position and
913  * dimensions, ensuring that its upper left corner falls at an iMCU boundary.
914  */
915  if (info->crop) {
916  /* Insert default values for unset crop parameters */
917  if (info->crop_xoffset_set == JCROP_UNSET)
918  info->crop_xoffset = 0; /* default to +0 */
919  if (info->crop_yoffset_set == JCROP_UNSET)
920  info->crop_yoffset = 0; /* default to +0 */
921  if (info->crop_xoffset >= info->output_width ||
922  info->crop_yoffset >= info->output_height)
923  ERREXIT(srcinfo, JERR_CONVERSION_NOTIMPL);
924  if (info->crop_width_set == JCROP_UNSET)
925  info->crop_width = info->output_width - info->crop_xoffset;
926  if (info->crop_height_set == JCROP_UNSET)
927  info->crop_height = info->output_height - info->crop_yoffset;
928  /* Ensure parameters are valid */
929  if (info->crop_width <= 0 || info->crop_width > info->output_width ||
930  info->crop_height <= 0 || info->crop_height > info->output_height ||
931  info->crop_xoffset > info->output_width - info->crop_width ||
932  info->crop_yoffset > info->output_height - info->crop_height)
933  ERREXIT(srcinfo, JERR_CONVERSION_NOTIMPL);
934  /* Convert negative crop offsets into regular offsets */
935  if (info->crop_xoffset_set == JCROP_NEG)
936  xoffset = info->output_width - info->crop_width - info->crop_xoffset;
937  else
938  xoffset = info->crop_xoffset;
939  if (info->crop_yoffset_set == JCROP_NEG)
940  yoffset = info->output_height - info->crop_height - info->crop_yoffset;
941  else
942  yoffset = info->crop_yoffset;
943  /* Now adjust so that upper left corner falls at an iMCU boundary */
944  if (info->crop_width_set == JCROP_FORCE)
945  info->output_width = info->crop_width;
946  else
947  info->output_width =
948  info->crop_width + (xoffset % info->iMCU_sample_width);
949  if (info->crop_height_set == JCROP_FORCE)
950  info->output_height = info->crop_height;
951  else
952  info->output_height =
953  info->crop_height + (yoffset % info->iMCU_sample_height);
954  /* Save x/y offsets measured in iMCUs */
955  info->x_crop_offset = xoffset / info->iMCU_sample_width;
956  info->y_crop_offset = yoffset / info->iMCU_sample_height;
957  } else {
958  info->x_crop_offset = 0;
959  info->y_crop_offset = 0;
960  }
961 
962  /* Figure out whether we need workspace arrays,
963  * and if so whether they are transposed relative to the source.
964  */
965  need_workspace = FALSE;
966  transpose_it = FALSE;
967  switch (info->transform) {
968  case JXFORM_NONE:
969  if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
970  need_workspace = TRUE;
971  /* No workspace needed if neither cropping nor transforming */
972  break;
973  case JXFORM_FLIP_H:
974  if (info->trim)
975  trim_right_edge(info, srcinfo->output_width);
976  if (info->y_crop_offset != 0 || info->slow_hflip)
977  need_workspace = TRUE;
978  /* do_flip_h_no_crop doesn't need a workspace array */
979  break;
980  case JXFORM_FLIP_V:
981  if (info->trim)
982  trim_bottom_edge(info, srcinfo->output_height);
983  /* Need workspace arrays having same dimensions as source image. */
984  need_workspace = TRUE;
985  break;
986  case JXFORM_TRANSPOSE:
987  /* transpose does NOT have to trim anything */
988  /* Need workspace arrays having transposed dimensions. */
989  need_workspace = TRUE;
990  transpose_it = TRUE;
991  break;
992  case JXFORM_TRANSVERSE:
993  if (info->trim) {
994  trim_right_edge(info, srcinfo->output_height);
995  trim_bottom_edge(info, srcinfo->output_width);
996  }
997  /* Need workspace arrays having transposed dimensions. */
998  need_workspace = TRUE;
999  transpose_it = TRUE;
1000  break;
1001  case JXFORM_ROT_90:
1002  if (info->trim)
1003  trim_right_edge(info, srcinfo->output_height);
1004  /* Need workspace arrays having transposed dimensions. */
1005  need_workspace = TRUE;
1006  transpose_it = TRUE;
1007  break;
1008  case JXFORM_ROT_180:
1009  if (info->trim) {
1010  trim_right_edge(info, srcinfo->output_width);
1011  trim_bottom_edge(info, srcinfo->output_height);
1012  }
1013  /* Need workspace arrays having same dimensions as source image. */
1014  need_workspace = TRUE;
1015  break;
1016  case JXFORM_ROT_270:
1017  if (info->trim)
1018  trim_bottom_edge(info, srcinfo->output_width);
1019  /* Need workspace arrays having transposed dimensions. */
1020  need_workspace = TRUE;
1021  transpose_it = TRUE;
1022  break;
1023  }
1024 
1025  /* Allocate workspace if needed.
1026  * Note that we allocate arrays padded out to the next iMCU boundary,
1027  * so that transform routines need not worry about missing edge blocks.
1028  */
1029  if (need_workspace) {
1030  coef_arrays = (jvirt_barray_ptr *)
1031  (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
1032  SIZEOF(jvirt_barray_ptr) * info->num_components);
1033  width_in_iMCUs = (JDIMENSION)
1034  jdiv_round_up((long) info->output_width,
1035  (long) info->iMCU_sample_width);
1036  height_in_iMCUs = (JDIMENSION)
1037  jdiv_round_up((long) info->output_height,
1038  (long) info->iMCU_sample_height);
1039  for (ci = 0; ci < info->num_components; ci++) {
1040  compptr = srcinfo->comp_info + ci;
1041  if (info->num_components == 1) {
1042  /* we're going to force samp factors to 1x1 in this case */
1043  h_samp_factor = v_samp_factor = 1;
1044  } else if (transpose_it) {
1045  h_samp_factor = compptr->v_samp_factor;
1046  v_samp_factor = compptr->h_samp_factor;
1047  } else {
1048  h_samp_factor = compptr->h_samp_factor;
1049  v_samp_factor = compptr->v_samp_factor;
1050  }
1051  width_in_blocks = width_in_iMCUs * h_samp_factor;
1052  height_in_blocks = height_in_iMCUs * v_samp_factor;
1053  coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
1054  ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
1055  width_in_blocks, height_in_blocks, (JDIMENSION) v_samp_factor);
1056  }
1057  info->workspace_coef_arrays = coef_arrays;
1058  } else
1059  info->workspace_coef_arrays = NULL;
1060 
1061  return TRUE;
1062 }
1063 
1064 
1065 /* Transpose destination image parameters */
1066 
1067 LOCAL(void)
1068 transpose_critical_parameters (j_compress_ptr dstinfo)
1069 {
1070  int tblno, i, j, ci, itemp;
1071  jpeg_component_info *compptr;
1072  JQUANT_TBL *qtblptr;
1073  JDIMENSION jtemp;
1074  UINT16 qtemp;
1075 
1076  /* Transpose image dimensions */
1077  jtemp = dstinfo->image_width;
1078  dstinfo->image_width = dstinfo->image_height;
1079  dstinfo->image_height = jtemp;
1080 #if JPEG_LIB_VERSION >= 70
1081  itemp = dstinfo->min_DCT_h_scaled_size;
1082  dstinfo->min_DCT_h_scaled_size = dstinfo->min_DCT_v_scaled_size;
1083  dstinfo->min_DCT_v_scaled_size = itemp;
1084 #endif
1085 
1086  /* Transpose sampling factors */
1087  for (ci = 0; ci < dstinfo->num_components; ci++) {
1088  compptr = dstinfo->comp_info + ci;
1089  itemp = compptr->h_samp_factor;
1090  compptr->h_samp_factor = compptr->v_samp_factor;
1091  compptr->v_samp_factor = itemp;
1092  }
1093 
1094  /* Transpose quantization tables */
1095  for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
1096  qtblptr = dstinfo->quant_tbl_ptrs[tblno];
1097  if (qtblptr != NULL) {
1098  for (i = 0; i < DCTSIZE; i++) {
1099  for (j = 0; j < i; j++) {
1100  qtemp = qtblptr->quantval[i*DCTSIZE+j];
1101  qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i];
1102  qtblptr->quantval[j*DCTSIZE+i] = qtemp;
1103  }
1104  }
1105  }
1106  }
1107 }
1108 
1109 
1110 /* Adjust Exif image parameters.
1111  *
1112  * We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible.
1113  */
1114 
1115 #if JPEG_LIB_VERSION >= 70
1116 LOCAL(void)
1117 adjust_exif_parameters (JOCTET FAR * data, unsigned int length,
1118  JDIMENSION new_width, JDIMENSION new_height)
1119 {
1120  boolean is_motorola; /* Flag for byte order */
1121  unsigned int number_of_tags, tagnum;
1122  unsigned int firstoffset, offset;
1123  JDIMENSION new_value;
1124 
1125  if (length < 12) return; /* Length of an IFD entry */
1126 
1127  /* Discover byte order */
1128  if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49)
1129  is_motorola = FALSE;
1130  else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D)
1131  is_motorola = TRUE;
1132  else
1133  return;
1134 
1135  /* Check Tag Mark */
1136  if (is_motorola) {
1137  if (GETJOCTET(data[2]) != 0) return;
1138  if (GETJOCTET(data[3]) != 0x2A) return;
1139  } else {
1140  if (GETJOCTET(data[3]) != 0) return;
1141  if (GETJOCTET(data[2]) != 0x2A) return;
1142  }
1143 
1144  /* Get first IFD offset (offset to IFD0) */
1145  if (is_motorola) {
1146  if (GETJOCTET(data[4]) != 0) return;
1147  if (GETJOCTET(data[5]) != 0) return;
1148  firstoffset = GETJOCTET(data[6]);
1149  firstoffset <<= 8;
1150  firstoffset += GETJOCTET(data[7]);
1151  } else {
1152  if (GETJOCTET(data[7]) != 0) return;
1153  if (GETJOCTET(data[6]) != 0) return;
1154  firstoffset = GETJOCTET(data[5]);
1155  firstoffset <<= 8;
1156  firstoffset += GETJOCTET(data[4]);
1157  }
1158  if (firstoffset > length - 2) return; /* check end of data segment */
1159 
1160  /* Get the number of directory entries contained in this IFD */
1161  if (is_motorola) {
1162  number_of_tags = GETJOCTET(data[firstoffset]);
1163  number_of_tags <<= 8;
1164  number_of_tags += GETJOCTET(data[firstoffset+1]);
1165  } else {
1166  number_of_tags = GETJOCTET(data[firstoffset+1]);
1167  number_of_tags <<= 8;
1168  number_of_tags += GETJOCTET(data[firstoffset]);
1169  }
1170  if (number_of_tags == 0) return;
1171  firstoffset += 2;
1172 
1173  /* Search for ExifSubIFD offset Tag in IFD0 */
1174  for (;;) {
1175  if (firstoffset > length - 12) return; /* check end of data segment */
1176  /* Get Tag number */
1177  if (is_motorola) {
1178  tagnum = GETJOCTET(data[firstoffset]);
1179  tagnum <<= 8;
1180  tagnum += GETJOCTET(data[firstoffset+1]);
1181  } else {
1182  tagnum = GETJOCTET(data[firstoffset+1]);
1183  tagnum <<= 8;
1184  tagnum += GETJOCTET(data[firstoffset]);
1185  }
1186  if (tagnum == 0x8769) break; /* found ExifSubIFD offset Tag */
1187  if (--number_of_tags == 0) return;
1188  firstoffset += 12;
1189  }
1190 
1191  /* Get the ExifSubIFD offset */
1192  if (is_motorola) {
1193  if (GETJOCTET(data[firstoffset+8]) != 0) return;
1194  if (GETJOCTET(data[firstoffset+9]) != 0) return;
1195  offset = GETJOCTET(data[firstoffset+10]);
1196  offset <<= 8;
1197  offset += GETJOCTET(data[firstoffset+11]);
1198  } else {
1199  if (GETJOCTET(data[firstoffset+11]) != 0) return;
1200  if (GETJOCTET(data[firstoffset+10]) != 0) return;
1201  offset = GETJOCTET(data[firstoffset+9]);
1202  offset <<= 8;
1203  offset += GETJOCTET(data[firstoffset+8]);
1204  }
1205  if (offset > length - 2) return; /* check end of data segment */
1206 
1207  /* Get the number of directory entries contained in this SubIFD */
1208  if (is_motorola) {
1209  number_of_tags = GETJOCTET(data[offset]);
1210  number_of_tags <<= 8;
1211  number_of_tags += GETJOCTET(data[offset+1]);
1212  } else {
1213  number_of_tags = GETJOCTET(data[offset+1]);
1214  number_of_tags <<= 8;
1215  number_of_tags += GETJOCTET(data[offset]);
1216  }
1217  if (number_of_tags < 2) return;
1218  offset += 2;
1219 
1220  /* Search for ExifImageWidth and ExifImageHeight Tags in this SubIFD */
1221  do {
1222  if (offset > length - 12) return; /* check end of data segment */
1223  /* Get Tag number */
1224  if (is_motorola) {
1225  tagnum = GETJOCTET(data[offset]);
1226  tagnum <<= 8;
1227  tagnum += GETJOCTET(data[offset+1]);
1228  } else {
1229  tagnum = GETJOCTET(data[offset+1]);
1230  tagnum <<= 8;
1231  tagnum += GETJOCTET(data[offset]);
1232  }
1233  if (tagnum == 0xA002 || tagnum == 0xA003) {
1234  if (tagnum == 0xA002)
1235  new_value = new_width; /* ExifImageWidth Tag */
1236  else
1237  new_value = new_height; /* ExifImageHeight Tag */
1238  if (is_motorola) {
1239  data[offset+2] = 0; /* Format = unsigned long (4 octets) */
1240  data[offset+3] = 4;
1241  data[offset+4] = 0; /* Number Of Components = 1 */
1242  data[offset+5] = 0;
1243  data[offset+6] = 0;
1244  data[offset+7] = 1;
1245  data[offset+8] = 0;
1246  data[offset+9] = 0;
1247  data[offset+10] = (JOCTET)((new_value >> 8) & 0xFF);
1248  data[offset+11] = (JOCTET)(new_value & 0xFF);
1249  } else {
1250  data[offset+2] = 4; /* Format = unsigned long (4 octets) */
1251  data[offset+3] = 0;
1252  data[offset+4] = 1; /* Number Of Components = 1 */
1253  data[offset+5] = 0;
1254  data[offset+6] = 0;
1255  data[offset+7] = 0;
1256  data[offset+8] = (JOCTET)(new_value & 0xFF);
1257  data[offset+9] = (JOCTET)((new_value >> 8) & 0xFF);
1258  data[offset+10] = 0;
1259  data[offset+11] = 0;
1260  }
1261  }
1262  offset += 12;
1263  } while (--number_of_tags);
1264 }
1265 #endif
1266 
1267 
1268 /* Adjust output image parameters as needed.
1269  *
1270  * This must be called after jpeg_copy_critical_parameters()
1271  * and before jpeg_write_coefficients().
1272  *
1273  * The return value is the set of virtual coefficient arrays to be written
1274  * (either the ones allocated by jtransform_request_workspace, or the
1275  * original source data arrays). The caller will need to pass this value
1276  * to jpeg_write_coefficients().
1277  */
1278 
1279 GLOBAL(jvirt_barray_ptr *)
1280 jtransform_adjust_parameters (j_decompress_ptr srcinfo,
1281  j_compress_ptr dstinfo,
1282  jvirt_barray_ptr *src_coef_arrays,
1283  jpeg_transform_info *info)
1284 {
1285  /* If force-to-grayscale is requested, adjust destination parameters */
1286  if (info->force_grayscale) {
1287  /* First, ensure we have YCbCr or grayscale data, and that the source's
1288  * Y channel is full resolution. (No reasonable person would make Y
1289  * be less than full resolution, so actually coping with that case
1290  * isn't worth extra code space. But we check it to avoid crashing.)
1291  */
1292  if (((dstinfo->jpeg_color_space == JCS_YCbCr &&
1293  dstinfo->num_components == 3) ||
1294  (dstinfo->jpeg_color_space == JCS_GRAYSCALE &&
1295  dstinfo->num_components == 1)) &&
1296  srcinfo->comp_info[0].h_samp_factor == srcinfo->max_h_samp_factor &&
1297  srcinfo->comp_info[0].v_samp_factor == srcinfo->max_v_samp_factor) {
1298  /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed
1299  * properly. Among other things, it sets the target h_samp_factor &
1300  * v_samp_factor to 1, which typically won't match the source.
1301  * We have to preserve the source's quantization table number, however.
1302  */
1303  int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no;
1304  jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE);
1305  dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no;
1306  } else {
1307  /* Sorry, can't do it */
1308  ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL);
1309  }
1310  } else if (info->num_components == 1) {
1311  /* For a single-component source, we force the destination sampling factors
1312  * to 1x1, with or without force_grayscale. This is useful because some
1313  * decoders choke on grayscale images with other sampling factors.
1314  */
1315  dstinfo->comp_info[0].h_samp_factor = 1;
1316  dstinfo->comp_info[0].v_samp_factor = 1;
1317  }
1318 
1319  /* Correct the destination's image dimensions as necessary
1320  * for rotate/flip, resize, and crop operations.
1321  */
1322 #if JPEG_LIB_VERSION >= 70
1323  dstinfo->jpeg_width = info->output_width;
1324  dstinfo->jpeg_height = info->output_height;
1325 #endif
1326 
1327  /* Transpose destination image parameters */
1328  switch (info->transform) {
1329  case JXFORM_TRANSPOSE:
1330  case JXFORM_TRANSVERSE:
1331  case JXFORM_ROT_90:
1332  case JXFORM_ROT_270:
1333 #if JPEG_LIB_VERSION < 70
1334  dstinfo->image_width = info->output_height;
1335  dstinfo->image_height = info->output_width;
1336 #endif
1337  transpose_critical_parameters(dstinfo);
1338  break;
1339  default:
1340 #if JPEG_LIB_VERSION < 70
1341  dstinfo->image_width = info->output_width;
1342  dstinfo->image_height = info->output_height;
1343 #endif
1344  break;
1345  }
1346 
1347  /* Adjust Exif properties */
1348  if (srcinfo->marker_list != NULL &&
1349  srcinfo->marker_list->marker == JPEG_APP0+1 &&
1350  srcinfo->marker_list->data_length >= 6 &&
1351  GETJOCTET(srcinfo->marker_list->data[0]) == 0x45 &&
1352  GETJOCTET(srcinfo->marker_list->data[1]) == 0x78 &&
1353  GETJOCTET(srcinfo->marker_list->data[2]) == 0x69 &&
1354  GETJOCTET(srcinfo->marker_list->data[3]) == 0x66 &&
1355  GETJOCTET(srcinfo->marker_list->data[4]) == 0 &&
1356  GETJOCTET(srcinfo->marker_list->data[5]) == 0) {
1357  /* Suppress output of JFIF marker */
1358  dstinfo->write_JFIF_header = FALSE;
1359 #if JPEG_LIB_VERSION >= 70
1360  /* Adjust Exif image parameters */
1361  if (dstinfo->jpeg_width != srcinfo->image_width ||
1362  dstinfo->jpeg_height != srcinfo->image_height)
1363  /* Align data segment to start of TIFF structure for parsing */
1364  adjust_exif_parameters(srcinfo->marker_list->data + 6,
1365  srcinfo->marker_list->data_length - 6,
1366  dstinfo->jpeg_width, dstinfo->jpeg_height);
1367 #endif
1368  }
1369 
1370  /* Return the appropriate output data set */
1371  if (info->workspace_coef_arrays != NULL)
1372  return info->workspace_coef_arrays;
1373  return src_coef_arrays;
1374 }
1375 
1376 
1377 /* Execute the actual transformation, if any.
1378  *
1379  * This must be called *after* jpeg_write_coefficients, because it depends
1380  * on jpeg_write_coefficients to have computed subsidiary values such as
1381  * the per-component width and height fields in the destination object.
1382  *
1383  * Note that some transformations will modify the source data arrays!
1384  */
1385 
1386 GLOBAL(void)
1387 jtransform_execute_transform (j_decompress_ptr srcinfo,
1388  j_compress_ptr dstinfo,
1389  jvirt_barray_ptr *src_coef_arrays,
1390  jpeg_transform_info *info)
1391 {
1392  jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays;
1393 
1394  /* Note: conditions tested here should match those in switch statement
1395  * in jtransform_request_workspace()
1396  */
1397  switch (info->transform) {
1398  case JXFORM_NONE:
1399  if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
1400  do_crop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1401  src_coef_arrays, dst_coef_arrays);
1402  break;
1403  case JXFORM_FLIP_H:
1404  if (info->y_crop_offset != 0 || info->slow_hflip)
1405  do_flip_h(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1406  src_coef_arrays, dst_coef_arrays);
1407  else
1408  do_flip_h_no_crop(srcinfo, dstinfo, info->x_crop_offset,
1409  src_coef_arrays);
1410  break;
1411  case JXFORM_FLIP_V:
1412  do_flip_v(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1413  src_coef_arrays, dst_coef_arrays);
1414  break;
1415  case JXFORM_TRANSPOSE:
1416  do_transpose(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1417  src_coef_arrays, dst_coef_arrays);
1418  break;
1419  case JXFORM_TRANSVERSE:
1420  do_transverse(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1421  src_coef_arrays, dst_coef_arrays);
1422  break;
1423  case JXFORM_ROT_90:
1424  do_rot_90(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1425  src_coef_arrays, dst_coef_arrays);
1426  break;
1427  case JXFORM_ROT_180:
1428  do_rot_180(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1429  src_coef_arrays, dst_coef_arrays);
1430  break;
1431  case JXFORM_ROT_270:
1432  do_rot_270(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
1433  src_coef_arrays, dst_coef_arrays);
1434  break;
1435  }
1436 }
1437 
1438 /* jtransform_perfect_transform
1439  *
1440  * Determine whether lossless transformation is perfectly
1441  * possible for a specified image and transformation.
1442  *
1443  * Inputs:
1444  * image_width, image_height: source image dimensions.
1445  * MCU_width, MCU_height: pixel dimensions of MCU.
1446  * transform: transformation identifier.
1447  * Parameter sources from initialized jpeg_struct
1448  * (after reading source header):
1449  * image_width = cinfo.image_width
1450  * image_height = cinfo.image_height
1451  * MCU_width = cinfo.max_h_samp_factor * cinfo.block_size
1452  * MCU_height = cinfo.max_v_samp_factor * cinfo.block_size
1453  * Result:
1454  * TRUE = perfect transformation possible
1455  * FALSE = perfect transformation not possible
1456  * (may use custom action then)
1457  */
1458 
1459 GLOBAL(boolean)
1460 jtransform_perfect_transform(JDIMENSION image_width, JDIMENSION image_height,
1461  int MCU_width, int MCU_height,
1462  JXFORM_CODE transform)
1463 {
1464  boolean result = TRUE; /* initialize TRUE */
1465 
1466  switch (transform) {
1467  case JXFORM_FLIP_H:
1468  case JXFORM_ROT_270:
1469  if (image_width % (JDIMENSION) MCU_width)
1470  result = FALSE;
1471  break;
1472  case JXFORM_FLIP_V:
1473  case JXFORM_ROT_90:
1474  if (image_height % (JDIMENSION) MCU_height)
1475  result = FALSE;
1476  break;
1477  case JXFORM_TRANSVERSE:
1478  case JXFORM_ROT_180:
1479  if (image_width % (JDIMENSION) MCU_width)
1480  result = FALSE;
1481  if (image_height % (JDIMENSION) MCU_height)
1482  result = FALSE;
1483  break;
1484  default:
1485  break;
1486  }
1487 
1488  return result;
1489 }
1490 
1491 #endif /* TRANSFORMS_SUPPORTED */
1492 
1493 
1494 /* Setup decompression object to save desired markers in memory.
1495  * This must be called before jpeg_read_header() to have the desired effect.
1496  */
1497 
1498 GLOBAL(void)
1499 jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option)
1500 {
1501 #ifdef SAVE_MARKERS_SUPPORTED
1502  int m;
1503 
1504  /* Save comments except under NONE option */
1505  if (option != JCOPYOPT_NONE) {
1506  jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF);
1507  }
1508  /* Save all types of APPn markers iff ALL option */
1509  if (option == JCOPYOPT_ALL) {
1510  for (m = 0; m < 16; m++)
1511  jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF);
1512  }
1513 #else
1514  (void) srcinfo; (void) option;
1515 #endif /* SAVE_MARKERS_SUPPORTED */
1516 }
1517 
1518 /* Copy markers saved in the given source object to the destination object.
1519  * This should be called just after jpeg_start_compress() or
1520  * jpeg_write_coefficients().
1521  * Note that those routines will have written the SOI, and also the
1522  * JFIF APP0 or Adobe APP14 markers if selected.
1523  */
1524 
1525 GLOBAL(void)
1526 jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
1528 {
1529  jpeg_saved_marker_ptr marker;
1530 
1531  /* In the current implementation, we don't actually need to examine the
1532  * option flag here; we just copy everything that got saved.
1533  * But to avoid confusion, we do not output JFIF and Adobe APP14 markers
1534  * if the encoder library already wrote one.
1535  */
1536  (void)option;
1537 
1538  for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) {
1539  if (dstinfo->write_JFIF_header &&
1540  marker->marker == JPEG_APP0 &&
1541  marker->data_length >= 5 &&
1542  GETJOCTET(marker->data[0]) == 0x4A &&
1543  GETJOCTET(marker->data[1]) == 0x46 &&
1544  GETJOCTET(marker->data[2]) == 0x49 &&
1545  GETJOCTET(marker->data[3]) == 0x46 &&
1546  GETJOCTET(marker->data[4]) == 0)
1547  continue; /* reject duplicate JFIF */
1548  if (dstinfo->write_Adobe_marker &&
1549  marker->marker == JPEG_APP0+14 &&
1550  marker->data_length >= 5 &&
1551  GETJOCTET(marker->data[0]) == 0x41 &&
1552  GETJOCTET(marker->data[1]) == 0x64 &&
1553  GETJOCTET(marker->data[2]) == 0x6F &&
1554  GETJOCTET(marker->data[3]) == 0x62 &&
1555  GETJOCTET(marker->data[4]) == 0x65)
1556  continue; /* reject duplicate Adobe */
1557 #ifdef NEED_FAR_POINTERS
1558  /* We could use jpeg_write_marker if the data weren't FAR... */
1559  {
1560  unsigned int i;
1561  jpeg_write_m_header(dstinfo, marker->marker, marker->data_length);
1562  for (i = 0; i < marker->data_length; i++)
1563  jpeg_write_m_byte(dstinfo, marker->data[i]);
1564  }
1565 #else
1566  jpeg_write_marker(dstinfo, marker->marker,
1567  marker->data, marker->data_length);
1568 #endif
1569  }
1570 }
const size_t count(pCandidateA->getBorderLines().size())
GLOBAL
#define SIZEOF(object)
Definition: jinclude.h:79
return NULL
JCOPY_OPTION option
Definition: transupp.h:208
j_compress_ptr dstinfo
Definition: transupp.h:211
jcopy_markers_execute(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, JCOPY_OPTION option)
Definition: transupp.c:1526
LOCAL
#define TRUE
MetadataImporterPluginType * result
int i
#define dstinfo_min_DCT_v_scaled_size
Definition: transupp.c:41
JXFORM_CODE
Definition: transupp.h:95
jcopy_markers_setup(j_decompress_ptr srcinfo, JCOPY_OPTION option)
Definition: transupp.c:1499
#define FALSE
#define dstinfo_min_DCT_h_scaled_size
Definition: transupp.c:40
static long jdiv_round_up(long a, long b)
Definition: transupp.c:29
JCOPY_OPTION
Definition: transupp.h:199
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo