Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 306679 | Differences between
and this patch

Collapse All | Expand All

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

Return to bug 306679