3
{ This file contains tables and miscellaneous utility routines needed
4
for both compression and decompression.
5
Note we prefix all global names with "j" to minimize conflicts with
6
a surrounding application. }
8
{ Source: jutils.c; Copyright (C) 1991-1996, Thomas G. Lane. }
20
{ jpeg_zigzag_order[i] is the zigzag-order position of the i'th element
21
of a DCT block read in natural order (left to right, top to bottom). }
24
{$ifdef FALSE} { This table is not actually needed in v6a }
27
jpeg_zigzag_order : array[0..DCTSIZE2] of int =
28
(0, 1, 5, 6, 14, 15, 27, 28,
29
2, 4, 7, 13, 16, 26, 29, 42,
30
3, 8, 12, 17, 25, 30, 41, 43,
31
9, 11, 18, 24, 31, 40, 44, 53,
32
10, 19, 23, 32, 39, 45, 52, 54,
33
20, 22, 33, 38, 46, 51, 55, 60,
34
21, 34, 37, 47, 50, 56, 59, 61,
35
35, 36, 48, 49, 57, 58, 62, 63);
40
{ jpeg_natural_order[i] is the natural-order position of the i'th element
43
When reading corrupted data, the Huffman decoders could attempt
44
to reference an entry beyond the end of this array (if the decoded
45
zero run length reaches past the end of the block). To prevent
46
wild stores without adding an inner-loop test, we put some extra
47
"63"s after the real entries. This will cause the extra coefficient
48
to be stored in location 63 of the block, not somewhere random.
49
The worst case would be a run-length of 15, which means we need 16
54
jpeg_natural_order : array[0..DCTSIZE2+16-1] of int =
55
(0, 1, 8, 16, 9, 2, 3, 10,
56
17, 24, 32, 25, 18, 11, 4, 5,
57
12, 19, 26, 33, 40, 48, 41, 34,
58
27, 20, 13, 6, 7, 14, 21, 28,
59
35, 42, 49, 56, 57, 50, 43, 36,
60
29, 22, 15, 23, 30, 37, 44, 51,
61
58, 59, 52, 45, 38, 31, 39, 46,
62
53, 60, 61, 54, 47, 55, 62, 63,
63
63, 63, 63, 63, 63, 63, 63, 63, { extra entries for safety in decoder }
64
63, 63, 63, 63, 63, 63, 63, 63);
68
{ Arithmetic utilities }
71
function jdiv_round_up (a : long; b : long) : long;
74
function jround_up (a : long; b : long) : long;
77
procedure jcopy_sample_rows (input_array : JSAMPARRAY;
79
output_array : JSAMPARRAY; dest_row : int;
80
num_rows : int; num_cols : JDIMENSION);
83
procedure jcopy_block_row (input_row : JBLOCKROW;
84
output_row : JBLOCKROW;
85
num_blocks : JDIMENSION);
88
procedure jzero_far (target : pointer;{far} bytestozero : size_t);
90
procedure FMEMZERO(target : pointer; size : size_t);
92
procedure FMEMCOPY(dest,src : pointer; size : size_t);
97
function jdiv_round_up (a : long; b : long) : long;
98
{ Compute a/b rounded up to next integer, ie, ceil(a/b) }
99
{ Assumes a >= 0, b > 0 }
101
jdiv_round_up := (a + b - long(1)) div b;
106
function jround_up (a : long; b : long) : long;
107
{ Compute a rounded up to next multiple of b, ie, ceil(a/b)*b }
108
{ Assumes a >= 0, b > 0 }
111
jround_up := a - (a mod b);
114
{ On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays
115
and coefficient-block arrays. This won't work on 80x86 because the arrays
116
are FAR and we're assuming a small-pointer memory model. However, some
117
DOS compilers provide far-pointer versions of memcpy() and memset() even
118
in the small-model libraries. These will be used if USE_FMEM is defined.
119
Otherwise, the routines below do it the hard way. (The performance cost
120
is not all that great, because these routines aren't very heavily used.) }
123
{$ifndef NEED_FAR_POINTERS} { normal case, same as regular macros }
124
procedure FMEMZERO(target : pointer; size : size_t);
126
FillChar(target^, size, 0);
129
procedure FMEMCOPY(dest,src : pointer; size : size_t);
131
Move(src^, dest^, size);
135
{$else} { 80x86 case, define if we can }
137
FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size))
138
FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size))
144
procedure jcopy_sample_rows (input_array : JSAMPARRAY; source_row : int;
145
output_array : JSAMPARRAY; dest_row : int;
146
num_rows : int; num_cols : JDIMENSION);
147
{ Copy some rows of samples from one place to another.
148
num_rows rows are copied from input_array[source_row++]
149
to output_array[dest_row++]; these areas may overlap for duplication.
150
The source and destination arrays must be at least as wide as num_cols. }
152
inptr, outptr : JSAMPLE_PTR; {register}
154
count : size_t; {register}
156
count : JDIMENSION; {register}
158
row : int; {register}
161
count := size_t(num_cols * SIZEOF(JSAMPLE));
163
Inc(JSAMPROW_PTR(input_array), source_row);
164
Inc(JSAMPROW_PTR(output_array), dest_row);
166
for row := pred(num_rows) downto 0 do
168
inptr := JSAMPLE_PTR(input_array^[0]);
169
Inc(JSAMPROW_PTR(input_array));
170
outptr := JSAMPLE_PTR(output_array^[0]);
171
Inc(JSAMPROW_PTR(output_array));
173
FMEMCOPY(outptr, inptr, count);
175
for count := pred(num_cols) downto 0 do
177
outptr^ := inptr^; { needn't bother with GETJSAMPLE() here }
187
procedure jcopy_block_row (input_row : JBLOCKROW;
188
output_row : JBLOCKROW;
189
num_blocks : JDIMENSION);
190
{ Copy a row of coefficient blocks from one place to another. }
193
FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
196
inptr, outptr : JCOEFPTR; {register}
197
count : long; {register}
199
inptr := JCOEFPTR (input_row);
200
outptr := JCOEFPTR (output_row);
201
for count := long(num_blocks) * DCTSIZE2 -1 downto 0 do
212
procedure jzero_far (target : pointer;{far} bytestozero : size_t);
213
{ Zero out a chunk of FAR memory. }
214
{ This might be sample-array data, block-array data, or alloc_large data. }
217
FMEMZERO(target, bytestozero);
221
count : size_t; {register}
224
for count := bytestozero-1 downto 0 do