1e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#if !defined(_FX_JPEG_TURBO_)
2e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/*
3e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * jutils.c
4e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *
5e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Copyright (C) 1991-1996, Thomas G. Lane.
6e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * This file is part of the Independent JPEG Group's software.
7e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * For conditions of distribution and use, see the accompanying README file.
8e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *
9e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * This file contains tables and miscellaneous utility routines needed
10e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * for both compression and decompression.
11e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Note we prefix all global names with "j" to minimize conflicts with
12e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * a surrounding application.
13e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */
14e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
15e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define JPEG_INTERNALS
16e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "jinclude.h"
17e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "jpeglib.h"
18e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
19e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
20e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/*
21e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * jpeg_zigzag_order[i] is the zigzag-order position of the i'th element
22e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * of a DCT block read in natural order (left to right, top to bottom).
23e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */
24e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
25e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#if 0				/* This table is not actually needed in v6a */
26e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
27e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovconst int jpeg_zigzag_order[DCTSIZE2] = {
28e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov   0,  1,  5,  6, 14, 15, 27, 28,
29e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov   2,  4,  7, 13, 16, 26, 29, 42,
30e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov   3,  8, 12, 17, 25, 30, 41, 43,
31e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov   9, 11, 18, 24, 31, 40, 44, 53,
32e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  10, 19, 23, 32, 39, 45, 52, 54,
33e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  20, 22, 33, 38, 46, 51, 55, 60,
34e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  21, 34, 37, 47, 50, 56, 59, 61,
35e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  35, 36, 48, 49, 57, 58, 62, 63
36e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov};
37e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
38e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
39e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
40e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/*
41e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * jpeg_natural_order[i] is the natural-order position of the i'th element
42e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * of zigzag order.
43e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *
44e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * When reading corrupted data, the Huffman decoders could attempt
45e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * to reference an entry beyond the end of this array (if the decoded
46e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * zero run length reaches past the end of the block).  To prevent
47e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * wild stores without adding an inner-loop test, we put some extra
48e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * "63"s after the real entries.  This will cause the extra coefficient
49e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * to be stored in location 63 of the block, not somewhere random.
50e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * The worst case would be a run-length of 15, which means we need 16
51e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * fake entries.
52e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */
53e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
54e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovconst int jpeg_natural_order[DCTSIZE2+16] = {
55e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  0,  1,  8, 16,  9,  2,  3, 10,
56e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 17, 24, 32, 25, 18, 11,  4,  5,
57e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 12, 19, 26, 33, 40, 48, 41, 34,
58e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 27, 20, 13,  6,  7, 14, 21, 28,
59e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 35, 42, 49, 56, 57, 50, 43, 36,
60e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 29, 22, 15, 23, 30, 37, 44, 51,
61e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 58, 59, 52, 45, 38, 31, 39, 46,
62e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 53, 60, 61, 54, 47, 55, 62, 63,
63e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
64e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 63, 63, 63, 63, 63, 63, 63, 63
65e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov};
66e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
67e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
68e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/*
69e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Arithmetic utilities
70e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */
71e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
72e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovGLOBAL(long)
73e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovjdiv_round_up (long a, long b)
74e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Compute a/b rounded up to next integer, ie, ceil(a/b) */
75e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Assumes a >= 0, b > 0 */
76e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
77e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  return (a + b - 1L) / b;
78e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
79e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
80e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
81e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovGLOBAL(long)
82e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovjround_up (long a, long b)
83e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */
84e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Assumes a >= 0, b > 0 */
85e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
86e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  a += b - 1L;
87e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  return a - (a % b);
88e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
89e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
90e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
91e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays
92e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * and coefficient-block arrays.  This won't work on 80x86 because the arrays
93e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * are FAR and we're assuming a small-pointer memory model.  However, some
94e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * DOS compilers provide far-pointer versions of memcpy() and memset() even
95e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * in the small-model libraries.  These will be used if USE_FMEM is defined.
96e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Otherwise, the routines below do it the hard way.  (The performance cost
97e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * is not all that great, because these routines aren't very heavily used.)
98e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */
99e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
100e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifndef NEED_FAR_POINTERS	/* normal case, same as regular macros */
101e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define FMEMCOPY(dest,src,size)	MEMCOPY(dest,src,size)
102e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define FMEMZERO(target,size)	MEMZERO(target,size)
103e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#else				/* 80x86 case, define if we can */
104e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef USE_FMEM
105e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define FMEMCOPY(dest,src,size)	_fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size))
106e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define FMEMZERO(target,size)	_fmemset((void FAR *)(target), 0, (size_t)(size))
107e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
108e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
109e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
110e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
111e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovGLOBAL(void)
112e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovjcopy_sample_rows (JSAMPARRAY input_array, int source_row,
113e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		   JSAMPARRAY output_array, int dest_row,
114e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		   int num_rows, JDIMENSION num_cols)
115e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Copy some rows of samples from one place to another.
116e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * num_rows rows are copied from input_array[source_row++]
117e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * to output_array[dest_row++]; these areas may overlap for duplication.
118e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * The source and destination arrays must be at least as wide as num_cols.
119e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */
120e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
121e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  register JSAMPROW inptr, outptr;
122e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef FMEMCOPY
123e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
124e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#else
125e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  register JDIMENSION count;
126e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
127e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  register int row;
128e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
129e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  input_array += source_row;
130e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  output_array += dest_row;
131e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
132e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  for (row = num_rows; row > 0; row--) {
133e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    inptr = *input_array++;
134e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    outptr = *output_array++;
135e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef FMEMCOPY
136e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FMEMCOPY(outptr, inptr, count);
137e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#else
138e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    for (count = num_cols; count > 0; count--)
139e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      *outptr++ = *inptr++;	/* needn't bother with GETJSAMPLE() here */
140e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
141e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  }
142e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
143e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
144e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
145e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovGLOBAL(void)
146e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovjcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
147e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 JDIMENSION num_blocks)
148e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Copy a row of coefficient blocks from one place to another. */
149e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
150e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef FMEMCOPY
151e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
152e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#else
153e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  register JCOEFPTR inptr, outptr;
154e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  register long count;
155e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
156e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  inptr = (JCOEFPTR) input_row;
157e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  outptr = (JCOEFPTR) output_row;
158e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) {
159e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    *outptr++ = *inptr++;
160e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  }
161e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
162e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
163e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
164e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
165e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovGLOBAL(void)
166e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovjzero_far (void FAR * target, size_t bytestozero)
167e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Zero out a chunk of FAR memory. */
168e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* This might be sample-array data, block-array data, or alloc_large data. */
169e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
170e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef FMEMZERO
171e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  FMEMZERO(target, bytestozero);
172e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#else
173e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  register char FAR * ptr = (char FAR *) target;
174e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  register size_t count;
175e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
176e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  for (count = bytestozero; count > 0; count--) {
177e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    *ptr++ = 0;
178e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  }
179e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif
180e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
181e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
182e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif //_FX_JPEG_TURBO_
183