Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6417 ashmew2 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
/* 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
#include "jinclude.h"
21
#include "jpeglib.h"
22
#include "transupp.h"		/* My own external interface */
23
 
24
 
25
#if TRANSFORMS_SUPPORTED
26
 
27
/*
28
 * Lossless image transformation routines.  These routines work on DCT
29
 * coefficient arrays and thus do not require any lossy decompression
30
 * or recompression of the image.
31
 * Thanks to Guido Vollbeding for the initial design and code of this feature.
32
 *
33
 * Horizontal flipping is done in-place, using a single top-to-bottom
34
 * pass through the virtual source array.  It will thus be much the
35
 * fastest option for images larger than main memory.
36
 *
37
 * The other routines require a set of destination virtual arrays, so they
38
 * need twice as much memory as jpegtran normally does.  The destination
39
 * arrays are always written in normal scan order (top to bottom) because
40
 * the virtual array manager expects this.  The source arrays will be scanned
41
 * in the corresponding order, which means multiple passes through the source
42
 * arrays for most of the transforms.  That could result in much thrashing
43
 * if the image is larger than main memory.
44
 *
45
 * Some notes about the operating environment of the individual transform
46
 * routines:
47
 * 1. Both the source and destination virtual arrays are allocated from the
48
 *    source JPEG object, and therefore should be manipulated by calling the
49
 *    source's memory manager.
50
 * 2. The destination's component count should be used.  It may be smaller
51
 *    than the source's when forcing to grayscale.
52
 * 3. Likewise the destination's sampling factors should be used.  When
53
 *    forcing to grayscale the destination's sampling factors will be all 1,
54
 *    and we may as well take that as the effective iMCU size.
55
 * 4. When "trim" is in effect, the destination's dimensions will be the
56
 *    trimmed values but the source's will be untrimmed.
57
 * 5. All the routines assume that the source and destination buffers are
58
 *    padded out to a full iMCU boundary.  This is true, although for the
59
 *    source buffer it is an undocumented property of jdcoefct.c.
60
 * Notes 2,3,4 boil down to this: generally we should use the destination's
61
 * dimensions and ignore the source's.
62
 */
63
 
64
 
65
LOCAL(void)
66
do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
67
	   jvirt_barray_ptr *src_coef_arrays)
68
/* Horizontal flip; done in-place, so no separate dest array is required */
69
{
70
  JDIMENSION MCU_cols, comp_width, blk_x, blk_y;
71
  int ci, k, offset_y;
72
  JBLOCKARRAY buffer;
73
  JCOEFPTR ptr1, ptr2;
74
  JCOEF temp1, temp2;
75
  jpeg_component_info *compptr;
76
 
77
  /* Horizontal mirroring of DCT blocks is accomplished by swapping
78
   * pairs of blocks in-place.  Within a DCT block, we perform horizontal
79
   * mirroring by changing the signs of odd-numbered columns.
80
   * Partial iMCUs at the right edge are left untouched.
81
   */
82
  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
83
 
84
  for (ci = 0; ci < dstinfo->num_components; ci++) {
85
    compptr = dstinfo->comp_info + ci;
86
    comp_width = MCU_cols * compptr->h_samp_factor;
87
    for (blk_y = 0; blk_y < compptr->height_in_blocks;
88
	 blk_y += compptr->v_samp_factor) {
89
      buffer = (*srcinfo->mem->access_virt_barray)
90
	((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y,
91
	 (JDIMENSION) compptr->v_samp_factor, TRUE);
92
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
93
	for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) {
94
	  ptr1 = buffer[offset_y][blk_x];
95
	  ptr2 = buffer[offset_y][comp_width - blk_x - 1];
96
	  /* this unrolled loop doesn't need to know which row it's on... */
97
	  for (k = 0; k < DCTSIZE2; k += 2) {
98
	    temp1 = *ptr1;	/* swap even column */
99
	    temp2 = *ptr2;
100
	    *ptr1++ = temp2;
101
	    *ptr2++ = temp1;
102
	    temp1 = *ptr1;	/* swap odd column with sign change */
103
	    temp2 = *ptr2;
104
	    *ptr1++ = -temp2;
105
	    *ptr2++ = -temp1;
106
	  }
107
	}
108
      }
109
    }
110
  }
111
}
112
 
113
 
114
LOCAL(void)
115
do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
116
	   jvirt_barray_ptr *src_coef_arrays,
117
	   jvirt_barray_ptr *dst_coef_arrays)
118
/* Vertical flip */
119
{
120
  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
121
  int ci, i, j, offset_y;
122
  JBLOCKARRAY src_buffer, dst_buffer;
123
  JBLOCKROW src_row_ptr, dst_row_ptr;
124
  JCOEFPTR src_ptr, dst_ptr;
125
  jpeg_component_info *compptr;
126
 
127
  /* We output into a separate array because we can't touch different
128
   * rows of the source virtual array simultaneously.  Otherwise, this
129
   * is a pretty straightforward analog of horizontal flip.
130
   * Within a DCT block, vertical mirroring is done by changing the signs
131
   * of odd-numbered rows.
132
   * Partial iMCUs at the bottom edge are copied verbatim.
133
   */
134
  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
135
 
136
  for (ci = 0; ci < dstinfo->num_components; ci++) {
137
    compptr = dstinfo->comp_info + ci;
138
    comp_height = MCU_rows * compptr->v_samp_factor;
139
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
140
	 dst_blk_y += compptr->v_samp_factor) {
141
      dst_buffer = (*srcinfo->mem->access_virt_barray)
142
	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
143
	 (JDIMENSION) compptr->v_samp_factor, TRUE);
144
      if (dst_blk_y < comp_height) {
145
	/* Row is within the mirrorable area. */
146
	src_buffer = (*srcinfo->mem->access_virt_barray)
147
	  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
148
	   comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor,
149
	   (JDIMENSION) compptr->v_samp_factor, FALSE);
150
      } else {
151
	/* Bottom-edge blocks will be copied verbatim. */
152
	src_buffer = (*srcinfo->mem->access_virt_barray)
153
	  ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y,
154
	   (JDIMENSION) compptr->v_samp_factor, FALSE);
155
      }
156
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
157
	if (dst_blk_y < comp_height) {
158
	  /* Row is within the mirrorable area. */
159
	  dst_row_ptr = dst_buffer[offset_y];
160
	  src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
161
	  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
162
	       dst_blk_x++) {
163
	    dst_ptr = dst_row_ptr[dst_blk_x];
164
	    src_ptr = src_row_ptr[dst_blk_x];
165
	    for (i = 0; i < DCTSIZE; i += 2) {
166
	      /* copy even row */
167
	      for (j = 0; j < DCTSIZE; j++)
168
		*dst_ptr++ = *src_ptr++;
169
	      /* copy odd row with sign change */
170
	      for (j = 0; j < DCTSIZE; j++)
171
		*dst_ptr++ = - *src_ptr++;
172
	    }
173
	  }
174
	} else {
175
	  /* Just copy row verbatim. */
176
	  jcopy_block_row(src_buffer[offset_y], dst_buffer[offset_y],
177
			  compptr->width_in_blocks);
178
	}
179
      }
180
    }
181
  }
182
}
183
 
184
 
185
LOCAL(void)
186
do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
187
	      jvirt_barray_ptr *src_coef_arrays,
188
	      jvirt_barray_ptr *dst_coef_arrays)
189
/* Transpose source into destination */
190
{
191
  JDIMENSION dst_blk_x, dst_blk_y;
192
  int ci, i, j, offset_x, offset_y;
193
  JBLOCKARRAY src_buffer, dst_buffer;
194
  JCOEFPTR src_ptr, dst_ptr;
195
  jpeg_component_info *compptr;
196
 
197
  /* Transposing pixels within a block just requires transposing the
198
   * DCT coefficients.
199
   * Partial iMCUs at the edges require no special treatment; we simply
200
   * process all the available DCT blocks for every component.
201
   */
202
  for (ci = 0; ci < dstinfo->num_components; ci++) {
203
    compptr = dstinfo->comp_info + ci;
204
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
205
	 dst_blk_y += compptr->v_samp_factor) {
206
      dst_buffer = (*srcinfo->mem->access_virt_barray)
207
	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
208
	 (JDIMENSION) compptr->v_samp_factor, TRUE);
209
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
210
	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
211
	     dst_blk_x += compptr->h_samp_factor) {
212
	  src_buffer = (*srcinfo->mem->access_virt_barray)
213
	    ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
214
	     (JDIMENSION) compptr->h_samp_factor, FALSE);
215
	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
216
	    src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
217
	    dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
218
	    for (i = 0; i < DCTSIZE; i++)
219
	      for (j = 0; j < DCTSIZE; j++)
220
		dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
221
	  }
222
	}
223
      }
224
    }
225
  }
226
}
227
 
228
 
229
LOCAL(void)
230
do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
231
	   jvirt_barray_ptr *src_coef_arrays,
232
	   jvirt_barray_ptr *dst_coef_arrays)
233
/* 90 degree rotation is equivalent to
234
 *   1. Transposing the image;
235
 *   2. Horizontal mirroring.
236
 * These two steps are merged into a single processing routine.
237
 */
238
{
239
  JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
240
  int ci, i, j, offset_x, offset_y;
241
  JBLOCKARRAY src_buffer, dst_buffer;
242
  JCOEFPTR src_ptr, dst_ptr;
243
  jpeg_component_info *compptr;
244
 
245
  /* Because of the horizontal mirror step, we can't process partial iMCUs
246
   * at the (output) right edge properly.  They just get transposed and
247
   * not mirrored.
248
   */
249
  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
250
 
251
  for (ci = 0; ci < dstinfo->num_components; ci++) {
252
    compptr = dstinfo->comp_info + ci;
253
    comp_width = MCU_cols * compptr->h_samp_factor;
254
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
255
	 dst_blk_y += compptr->v_samp_factor) {
256
      dst_buffer = (*srcinfo->mem->access_virt_barray)
257
	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
258
	 (JDIMENSION) compptr->v_samp_factor, TRUE);
259
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
260
	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
261
	     dst_blk_x += compptr->h_samp_factor) {
262
	  src_buffer = (*srcinfo->mem->access_virt_barray)
263
	    ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
264
	     (JDIMENSION) compptr->h_samp_factor, FALSE);
265
	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
266
	    src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
267
	    if (dst_blk_x < comp_width) {
268
	      /* Block is within the mirrorable area. */
269
	      dst_ptr = dst_buffer[offset_y]
270
		[comp_width - dst_blk_x - offset_x - 1];
271
	      for (i = 0; i < DCTSIZE; i++) {
272
		for (j = 0; j < DCTSIZE; j++)
273
		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
274
		i++;
275
		for (j = 0; j < DCTSIZE; j++)
276
		  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
277
	      }
278
	    } else {
279
	      /* Edge blocks are transposed but not mirrored. */
280
	      dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
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
	    }
285
	  }
286
	}
287
      }
288
    }
289
  }
290
}
291
 
292
 
293
LOCAL(void)
294
do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
295
	    jvirt_barray_ptr *src_coef_arrays,
296
	    jvirt_barray_ptr *dst_coef_arrays)
297
/* 270 degree rotation is equivalent to
298
 *   1. Horizontal mirroring;
299
 *   2. Transposing the image.
300
 * These two steps are merged into a single processing routine.
301
 */
302
{
303
  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
304
  int ci, i, j, offset_x, offset_y;
305
  JBLOCKARRAY src_buffer, dst_buffer;
306
  JCOEFPTR src_ptr, dst_ptr;
307
  jpeg_component_info *compptr;
308
 
309
  /* Because of the horizontal mirror step, we can't process partial iMCUs
310
   * at the (output) bottom edge properly.  They just get transposed and
311
   * not mirrored.
312
   */
313
  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
314
 
315
  for (ci = 0; ci < dstinfo->num_components; ci++) {
316
    compptr = dstinfo->comp_info + ci;
317
    comp_height = MCU_rows * compptr->v_samp_factor;
318
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
319
	 dst_blk_y += compptr->v_samp_factor) {
320
      dst_buffer = (*srcinfo->mem->access_virt_barray)
321
	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
322
	 (JDIMENSION) compptr->v_samp_factor, TRUE);
323
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
324
	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
325
	     dst_blk_x += compptr->h_samp_factor) {
326
	  src_buffer = (*srcinfo->mem->access_virt_barray)
327
	    ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
328
	     (JDIMENSION) compptr->h_samp_factor, FALSE);
329
	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
330
	    dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
331
	    if (dst_blk_y < comp_height) {
332
	      /* Block is within the mirrorable area. */
333
	      src_ptr = src_buffer[offset_x]
334
		[comp_height - dst_blk_y - offset_y - 1];
335
	      for (i = 0; i < DCTSIZE; i++) {
336
		for (j = 0; j < DCTSIZE; j++) {
337
		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
338
		  j++;
339
		  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
340
		}
341
	      }
342
	    } else {
343
	      /* Edge blocks are transposed but not mirrored. */
344
	      src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
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
	    }
349
	  }
350
	}
351
      }
352
    }
353
  }
354
}
355
 
356
 
357
LOCAL(void)
358
do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
359
	    jvirt_barray_ptr *src_coef_arrays,
360
	    jvirt_barray_ptr *dst_coef_arrays)
361
/* 180 degree rotation is equivalent to
362
 *   1. Vertical mirroring;
363
 *   2. Horizontal mirroring.
364
 * These two steps are merged into a single processing routine.
365
 */
366
{
367
  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
368
  int ci, i, j, offset_y;
369
  JBLOCKARRAY src_buffer, dst_buffer;
370
  JBLOCKROW src_row_ptr, dst_row_ptr;
371
  JCOEFPTR src_ptr, dst_ptr;
372
  jpeg_component_info *compptr;
373
 
374
  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
375
  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
376
 
377
  for (ci = 0; ci < dstinfo->num_components; ci++) {
378
    compptr = dstinfo->comp_info + ci;
379
    comp_width = MCU_cols * compptr->h_samp_factor;
380
    comp_height = MCU_rows * compptr->v_samp_factor;
381
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
382
	 dst_blk_y += compptr->v_samp_factor) {
383
      dst_buffer = (*srcinfo->mem->access_virt_barray)
384
	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
385
	 (JDIMENSION) compptr->v_samp_factor, TRUE);
386
      if (dst_blk_y < comp_height) {
387
	/* Row is within the vertically mirrorable area. */
388
	src_buffer = (*srcinfo->mem->access_virt_barray)
389
	  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
390
	   comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor,
391
	   (JDIMENSION) compptr->v_samp_factor, FALSE);
392
      } else {
393
	/* Bottom-edge rows are only mirrored horizontally. */
394
	src_buffer = (*srcinfo->mem->access_virt_barray)
395
	  ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y,
396
	   (JDIMENSION) compptr->v_samp_factor, FALSE);
397
      }
398
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
399
	if (dst_blk_y < comp_height) {
400
	  /* Row is within the mirrorable area. */
401
	  dst_row_ptr = dst_buffer[offset_y];
402
	  src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
403
	  /* Process the blocks that can be mirrored both ways. */
404
	  for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
405
	    dst_ptr = dst_row_ptr[dst_blk_x];
406
	    src_ptr = src_row_ptr[comp_width - dst_blk_x - 1];
407
	    for (i = 0; i < DCTSIZE; i += 2) {
408
	      /* For even row, negate every odd column. */
409
	      for (j = 0; j < DCTSIZE; j += 2) {
410
		*dst_ptr++ = *src_ptr++;
411
		*dst_ptr++ = - *src_ptr++;
412
	      }
413
	      /* For odd row, negate every even column. */
414
	      for (j = 0; j < DCTSIZE; j += 2) {
415
		*dst_ptr++ = - *src_ptr++;
416
		*dst_ptr++ = *src_ptr++;
417
	      }
418
	    }
419
	  }
420
	  /* Any remaining right-edge blocks are only mirrored vertically. */
421
	  for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
422
	    dst_ptr = dst_row_ptr[dst_blk_x];
423
	    src_ptr = src_row_ptr[dst_blk_x];
424
	    for (i = 0; i < DCTSIZE; i += 2) {
425
	      for (j = 0; j < DCTSIZE; j++)
426
		*dst_ptr++ = *src_ptr++;
427
	      for (j = 0; j < DCTSIZE; j++)
428
		*dst_ptr++ = - *src_ptr++;
429
	    }
430
	  }
431
	} else {
432
	  /* Remaining rows are just mirrored horizontally. */
433
	  dst_row_ptr = dst_buffer[offset_y];
434
	  src_row_ptr = src_buffer[offset_y];
435
	  /* Process the blocks that can be mirrored. */
436
	  for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
437
	    dst_ptr = dst_row_ptr[dst_blk_x];
438
	    src_ptr = src_row_ptr[comp_width - dst_blk_x - 1];
439
	    for (i = 0; i < DCTSIZE2; i += 2) {
440
	      *dst_ptr++ = *src_ptr++;
441
	      *dst_ptr++ = - *src_ptr++;
442
	    }
443
	  }
444
	  /* Any remaining right-edge blocks are only copied. */
445
	  for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
446
	    dst_ptr = dst_row_ptr[dst_blk_x];
447
	    src_ptr = src_row_ptr[dst_blk_x];
448
	    for (i = 0; i < DCTSIZE2; i++)
449
	      *dst_ptr++ = *src_ptr++;
450
	  }
451
	}
452
      }
453
    }
454
  }
455
}
456
 
457
 
458
LOCAL(void)
459
do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
460
	       jvirt_barray_ptr *src_coef_arrays,
461
	       jvirt_barray_ptr *dst_coef_arrays)
462
/* Transverse transpose is equivalent to
463
 *   1. 180 degree rotation;
464
 *   2. Transposition;
465
 * or
466
 *   1. Horizontal mirroring;
467
 *   2. Transposition;
468
 *   3. Horizontal mirroring.
469
 * These steps are merged into a single processing routine.
470
 */
471
{
472
  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
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
  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
479
  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
480
 
481
  for (ci = 0; ci < dstinfo->num_components; ci++) {
482
    compptr = dstinfo->comp_info + ci;
483
    comp_width = MCU_cols * compptr->h_samp_factor;
484
    comp_height = MCU_rows * compptr->v_samp_factor;
485
    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
486
	 dst_blk_y += compptr->v_samp_factor) {
487
      dst_buffer = (*srcinfo->mem->access_virt_barray)
488
	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
489
	 (JDIMENSION) compptr->v_samp_factor, TRUE);
490
      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
491
	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
492
	     dst_blk_x += compptr->h_samp_factor) {
493
	  src_buffer = (*srcinfo->mem->access_virt_barray)
494
	    ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
495
	     (JDIMENSION) compptr->h_samp_factor, FALSE);
496
	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
497
	    if (dst_blk_y < comp_height) {
498
	      src_ptr = src_buffer[offset_x]
499
		[comp_height - dst_blk_y - offset_y - 1];
500
	      if (dst_blk_x < comp_width) {
501
		/* Block is within the mirrorable area. */
502
		dst_ptr = dst_buffer[offset_y]
503
		  [comp_width - dst_blk_x - offset_x - 1];
504
		for (i = 0; i < DCTSIZE; i++) {
505
		  for (j = 0; j < DCTSIZE; j++) {
506
		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
507
		    j++;
508
		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
509
		  }
510
		  i++;
511
		  for (j = 0; j < DCTSIZE; j++) {
512
		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
513
		    j++;
514
		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
515
		  }
516
		}
517
	      } else {
518
		/* Right-edge blocks are mirrored in y only */
519
		dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
520
		for (i = 0; i < DCTSIZE; 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
	      }
528
	    } else {
529
	      src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
530
	      if (dst_blk_x < comp_width) {
531
		/* Bottom-edge blocks are mirrored in x only */
532
		dst_ptr = dst_buffer[offset_y]
533
		  [comp_width - dst_blk_x - offset_x - 1];
534
		for (i = 0; i < DCTSIZE; i++) {
535
		  for (j = 0; j < DCTSIZE; j++)
536
		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
537
		  i++;
538
		  for (j = 0; j < DCTSIZE; j++)
539
		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
540
		}
541
	      } else {
542
		/* At lower right corner, just transpose, no mirroring */
543
		dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
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
	      }
548
	    }
549
	  }
550
	}
551
      }
552
    }
553
  }
554
}
555
 
556
 
557
/* Request any required workspace.
558
 *
559
 * We allocate the workspace virtual arrays from the source decompression
560
 * object, so that all the arrays (both the original data and the workspace)
561
 * will be taken into account while making memory management decisions.
562
 * Hence, this routine must be called after jpeg_read_header (which reads
563
 * the image dimensions) and before jpeg_read_coefficients (which realizes
564
 * the source's virtual arrays).
565
 */
566
 
567
GLOBAL(void)
568
jtransform_request_workspace (j_decompress_ptr srcinfo,
569
			      jpeg_transform_info *info)
570
{
571
  jvirt_barray_ptr *coef_arrays = NULL;
572
  jpeg_component_info *compptr;
573
  int ci;
574
 
575
  if (info->force_grayscale &&
576
      srcinfo->jpeg_color_space == JCS_YCbCr &&
577
      srcinfo->num_components == 3) {
578
    /* We'll only process the first component */
579
    info->num_components = 1;
580
  } else {
581
    /* Process all the components */
582
    info->num_components = srcinfo->num_components;
583
  }
584
 
585
  switch (info->transform) {
586
  case JXFORM_NONE:
587
  case JXFORM_FLIP_H:
588
    /* Don't need a workspace array */
589
    break;
590
  case JXFORM_FLIP_V:
591
  case JXFORM_ROT_180:
592
    /* Need workspace arrays having same dimensions as source image.
593
     * Note that we allocate arrays padded out to the next iMCU boundary,
594
     * so that transform routines need not worry about missing edge blocks.
595
     */
596
    coef_arrays = (jvirt_barray_ptr *)
597
      (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
598
	SIZEOF(jvirt_barray_ptr) * info->num_components);
599
    for (ci = 0; ci < info->num_components; ci++) {
600
      compptr = srcinfo->comp_info + ci;
601
      coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
602
	((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
603
	 (JDIMENSION) jround_up((long) compptr->width_in_blocks,
604
				(long) compptr->h_samp_factor),
605
	 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
606
				(long) compptr->v_samp_factor),
607
	 (JDIMENSION) compptr->v_samp_factor);
608
    }
609
    break;
610
  case JXFORM_TRANSPOSE:
611
  case JXFORM_TRANSVERSE:
612
  case JXFORM_ROT_90:
613
  case JXFORM_ROT_270:
614
    /* Need workspace arrays having transposed dimensions.
615
     * Note that we allocate arrays padded out to the next iMCU boundary,
616
     * so that transform routines need not worry about missing edge blocks.
617
     */
618
    coef_arrays = (jvirt_barray_ptr *)
619
      (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
620
	SIZEOF(jvirt_barray_ptr) * info->num_components);
621
    for (ci = 0; ci < info->num_components; ci++) {
622
      compptr = srcinfo->comp_info + ci;
623
      coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
624
	((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
625
	 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
626
				(long) compptr->v_samp_factor),
627
	 (JDIMENSION) jround_up((long) compptr->width_in_blocks,
628
				(long) compptr->h_samp_factor),
629
	 (JDIMENSION) compptr->h_samp_factor);
630
    }
631
    break;
632
  }
633
  info->workspace_coef_arrays = coef_arrays;
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
GLOBAL(void)
819
jtransform_execute_transformation (j_decompress_ptr srcinfo,
820
				   j_compress_ptr dstinfo,
821
				   jvirt_barray_ptr *src_coef_arrays,
822
				   jpeg_transform_info *info)
823
{
824
  jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays;
825
 
826
  switch (info->transform) {
827
  case JXFORM_NONE:
828
    break;
829
  case JXFORM_FLIP_H:
830
    do_flip_h(srcinfo, dstinfo, src_coef_arrays);
831
    break;
832
  case JXFORM_FLIP_V:
833
    do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
834
    break;
835
  case JXFORM_TRANSPOSE:
836
    do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
837
    break;
838
  case JXFORM_TRANSVERSE:
839
    do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
840
    break;
841
  case JXFORM_ROT_90:
842
    do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
843
    break;
844
  case JXFORM_ROT_180:
845
    do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
846
    break;
847
  case JXFORM_ROT_270:
848
    do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
849
    break;
850
  }
851
}
852
 
853
#endif /* TRANSFORMS_SUPPORTED */
854
 
855
 
856
/* Setup decompression object to save desired markers in memory.
857
 * This must be called before jpeg_read_header() to have the desired effect.
858
 */
859
 
860
GLOBAL(void)
861
jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option)
862
{
863
#ifdef SAVE_MARKERS_SUPPORTED
864
  int m;
865
 
866
  /* Save comments except under NONE option */
867
  if (option != JCOPYOPT_NONE) {
868
    jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF);
869
  }
870
  /* Save all types of APPn markers iff ALL option */
871
  if (option == JCOPYOPT_ALL) {
872
    for (m = 0; m < 16; m++)
873
      jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF);
874
  }
875
#endif /* SAVE_MARKERS_SUPPORTED */
876
}
877
 
878
/* Copy markers saved in the given source object to the destination object.
879
 * This should be called just after jpeg_start_compress() or
880
 * jpeg_write_coefficients().
881
 * Note that those routines will have written the SOI, and also the
882
 * JFIF APP0 or Adobe APP14 markers if selected.
883
 */
884
 
885
GLOBAL(void)
886
jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
887
		       JCOPY_OPTION option)
888
{
889
  jpeg_saved_marker_ptr marker;
890
 
891
  /* In the current implementation, we don't actually need to examine the
892
   * option flag here; we just copy everything that got saved.
893
   * But to avoid confusion, we do not output JFIF and Adobe APP14 markers
894
   * if the encoder library already wrote one.
895
   */
896
  for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) {
897
    if (dstinfo->write_JFIF_header &&
898
	marker->marker == JPEG_APP0 &&
899
	marker->data_length >= 5 &&
900
	GETJOCTET(marker->data[0]) == 0x4A &&
901
	GETJOCTET(marker->data[1]) == 0x46 &&
902
	GETJOCTET(marker->data[2]) == 0x49 &&
903
	GETJOCTET(marker->data[3]) == 0x46 &&
904
	GETJOCTET(marker->data[4]) == 0)
905
      continue;			/* reject duplicate JFIF */
906
    if (dstinfo->write_Adobe_marker &&
907
	marker->marker == JPEG_APP0+14 &&
908
	marker->data_length >= 5 &&
909
	GETJOCTET(marker->data[0]) == 0x41 &&
910
	GETJOCTET(marker->data[1]) == 0x64 &&
911
	GETJOCTET(marker->data[2]) == 0x6F &&
912
	GETJOCTET(marker->data[3]) == 0x62 &&
913
	GETJOCTET(marker->data[4]) == 0x65)
914
      continue;			/* reject duplicate Adobe */
915
#ifdef NEED_FAR_POINTERS
916
    /* We could use jpeg_write_marker if the data weren't FAR... */
917
    {
918
      unsigned int i;
919
      jpeg_write_m_header(dstinfo, marker->marker, marker->data_length);
920
      for (i = 0; i < marker->data_length; i++)
921
	jpeg_write_m_byte(dstinfo, marker->data[i]);
922
    }
923
#else
924
    jpeg_write_marker(dstinfo, marker->marker,
925
		      marker->data, marker->data_length);
926
#endif
927
  }
928
}