DEADSOFTWARE

hopefully no more windows
[d2df-editor.git] / src / lib / vampimg / JpegLib / imjidctred.pas
1 unit imjidctred;
4 { This file contains inverse-DCT routines that produce reduced-size output:
5 either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block.
7 The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M)
8 algorithm used in jidctint.c. We simply replace each 8-to-8 1-D IDCT step
9 with an 8-to-4 step that produces the four averages of two adjacent outputs
10 (or an 8-to-2 step producing two averages of four outputs, for 2x2 output).
11 These steps were derived by computing the corresponding values at the end
12 of the normal LL&M code, then simplifying as much as possible.
14 1x1 is trivial: just take the DC coefficient divided by 8.
16 See jidctint.c for additional comments. }
19 { Original : jidctred.c ; Copyright (C) 1994-1998, Thomas G. Lane. }
21 interface
23 {$I imjconfig.inc}
25 uses
26 imjmorecfg,
27 imjinclude,
28 imjpeglib,
29 imjdct; { Private declarations for DCT subsystem }
31 { Perform dequantization and inverse DCT on one block of coefficients,
32 producing a reduced-size 1x1 output block. }
34 {GLOBAL}
35 procedure jpeg_idct_1x1 (cinfo : j_decompress_ptr;
36 compptr : jpeg_component_info_ptr;
37 coef_block : JCOEFPTR;
38 output_buf : JSAMPARRAY;
39 output_col : JDIMENSION);
41 { Perform dequantization and inverse DCT on one block of coefficients,
42 producing a reduced-size 2x2 output block. }
44 {GLOBAL}
45 procedure jpeg_idct_2x2 (cinfo : j_decompress_ptr;
46 compptr : jpeg_component_info_ptr;
47 coef_block : JCOEFPTR;
48 output_buf : JSAMPARRAY;
49 output_col : JDIMENSION);
51 { Perform dequantization and inverse DCT on one block of coefficients,
52 producing a reduced-size 4x4 output block. }
54 {GLOBAL}
55 procedure jpeg_idct_4x4 (cinfo : j_decompress_ptr;
56 compptr : jpeg_component_info_ptr;
57 coef_block : JCOEFPTR;
58 output_buf : JSAMPARRAY;
59 output_col : JDIMENSION);
61 implementation
63 { This module is specialized to the case DCTSIZE = 8. }
65 {$ifndef DCTSIZE_IS_8}
66 Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err }
67 {$endif}
70 { Scaling is the same as in jidctint.c. }
72 {$ifdef BITS_IN_JSAMPLE_IS_8}
73 const
74 CONST_BITS = 13;
75 PASS1_BITS = 2;
76 {$else}
77 const
78 CONST_BITS = 13;
79 PASS1_BITS = 1; { lose a little precision to avoid overflow }
80 {$endif}
82 const
83 FIX_0_211164243 = INT32(Round((INT32(1) shl CONST_BITS) * 0.211164243)); {1730}
84 FIX_0_509795579 = INT32(Round((INT32(1) shl CONST_BITS) * 0.509795579)); {4176}
85 FIX_0_601344887 = INT32(Round((INT32(1) shl CONST_BITS) * 0.601344887)); {4926}
86 FIX_0_720959822 = INT32(Round((INT32(1) shl CONST_BITS) * 0.720959822)); {5906}
87 FIX_0_765366865 = INT32(Round((INT32(1) shl CONST_BITS) * 0.765366865)); {6270}
88 FIX_0_850430095 = INT32(Round((INT32(1) shl CONST_BITS) * 0.850430095)); {6967}
89 FIX_0_899976223 = INT32(Round((INT32(1) shl CONST_BITS) * 0.899976223)); {7373}
90 FIX_1_061594337 = INT32(Round((INT32(1) shl CONST_BITS) * 1.061594337)); {8697}
91 FIX_1_272758580 = INT32(Round((INT32(1) shl CONST_BITS) * 1.272758580)); {10426}
92 FIX_1_451774981 = INT32(Round((INT32(1) shl CONST_BITS) * 1.451774981)); {11893}
93 FIX_1_847759065 = INT32(Round((INT32(1) shl CONST_BITS) * 1.847759065)); {15137}
94 FIX_2_172734803 = INT32(Round((INT32(1) shl CONST_BITS) * 2.172734803)); {17799}
95 FIX_2_562915447 = INT32(Round((INT32(1) shl CONST_BITS) * 2.562915447)); {20995}
96 FIX_3_624509785 = INT32(Round((INT32(1) shl CONST_BITS) * 3.624509785)); {29692}
99 { Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
100 For 8-bit samples with the recommended scaling, all the variable
101 and constant values involved are no more than 16 bits wide, so a
102 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
103 For 12-bit samples, a full 32-bit multiplication will be needed. }
105 {$ifdef BITS_IN_JSAMPLE_IS_8}
107 {function Multiply(X, Y: Integer): integer; assembler;
108 asm
109 mov ax, X
110 imul Y
111 mov al, ah
112 mov ah, dl
113 end;}
115 {MULTIPLY16C16(var,const)}
116 function Multiply(X, Y: Integer): INT32;
117 begin
118 Multiply := X*INT32(Y);
119 end;
122 {$else}
123 function Multiply(X, Y: INT32): INT32;
124 begin
125 Multiply := X*Y;
126 end;
127 {$endif}
130 { Dequantize a coefficient by multiplying it by the multiplier-table
131 entry; produce an int result. In this module, both inputs and result
132 are 16 bits or less, so either int or short multiply will work. }
134 function DEQUANTIZE(coef,quantval : int) : int;
135 begin
136 Dequantize := ( ISLOW_MULT_TYPE(coef) * quantval);
137 end;
140 { Descale and correctly round an INT32 value that's scaled by N bits.
141 We assume RIGHT_SHIFT rounds towards minus infinity, so adding
142 the fudge factor is correct for either sign of X. }
144 function DESCALE(x : INT32; n : int) : INT32;
145 var
146 shift_temp : INT32;
147 begin
148 {$ifdef RIGHT_SHIFT_IS_UNSIGNED}
149 shift_temp := x + (INT32(1) shl (n-1));
150 if shift_temp < 0 then
151 Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n))
152 else
153 Descale := (shift_temp shr n);
154 {$else}
155 Descale := (x + (INT32(1) shl (n-1)) shr n;
156 {$endif}
157 end;
159 { Perform dequantization and inverse DCT on one block of coefficients,
160 producing a reduced-size 4x4 output block. }
162 {GLOBAL}
163 procedure jpeg_idct_4x4 (cinfo : j_decompress_ptr;
164 compptr : jpeg_component_info_ptr;
165 coef_block : JCOEFPTR;
166 output_buf : JSAMPARRAY;
167 output_col : JDIMENSION);
168 type
169 PWorkspace = ^TWorkspace;
170 TWorkspace = array[0..(DCTSIZE*4)-1] of int; { buffers data between passes }
171 var
172 tmp0, tmp2, tmp10, tmp12 : INT32;
173 z1, z2, z3, z4 : INT32;
174 inptr : JCOEFPTR;
175 quantptr : ISLOW_MULT_TYPE_FIELD_PTR;
176 wsptr : PWorkspace;
177 outptr : JSAMPROW;
178 range_limit : JSAMPROW;
179 ctr : int;
180 workspace : TWorkspace; { buffers data between passes }
181 {SHIFT_TEMPS}
182 var
183 dcval : int;
184 var
185 dcval_ : JSAMPLE;
186 begin
187 { Each IDCT routine is responsible for range-limiting its results and
188 converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could
189 be quite far out of range if the input data is corrupt, so a bulletproof
190 range-limiting step is required. We use a mask-and-table-lookup method
191 to do the combined operations quickly. See the comments with
192 prepare_range_limit_table (in jdmaster.c) for more info. }
194 range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE]));
196 { Pass 1: process columns from input, store into work array. }
198 inptr := coef_block;
199 quantptr := ISLOW_MULT_TYPE_FIELD_PTR (compptr^.dct_table);
200 wsptr := @workspace;
201 for ctr := DCTSIZE downto 1 do
202 begin
203 { Don't bother to process column 4, because second pass won't use it }
204 if (ctr = DCTSIZE-4) then
205 begin
206 Inc(JCOEF_PTR(inptr));
207 Inc(ISLOW_MULT_TYPE_PTR(quantptr));
208 Inc(int_ptr(wsptr));
210 continue;
211 end;
212 if (inptr^[DCTSIZE*1]=0) and (inptr^[DCTSIZE*2]=0) and (inptr^[DCTSIZE*3]=0) and
213 (inptr^[DCTSIZE*5]=0) and (inptr^[DCTSIZE*6]=0) and (inptr^[DCTSIZE*7]=0) then
214 begin
215 { AC terms all zero; we need not examine term 4 for 4x4 output }
216 dcval := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*0]) *
217 quantptr^[DCTSIZE*0]) shl PASS1_BITS;
219 wsptr^[DCTSIZE*0] := dcval;
220 wsptr^[DCTSIZE*1] := dcval;
221 wsptr^[DCTSIZE*2] := dcval;
222 wsptr^[DCTSIZE*3] := dcval;
224 Inc(JCOEF_PTR(inptr));
225 Inc(ISLOW_MULT_TYPE_PTR(quantptr));
226 Inc(int_ptr(wsptr));
228 continue;
229 end;
231 { Even part }
233 tmp0 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*0]) * quantptr^[DCTSIZE*0]);
235 tmp0 := tmp0 shl (CONST_BITS+1);
237 z2 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*2]) * quantptr^[DCTSIZE*2]);
238 z3 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*6]) * quantptr^[DCTSIZE*6]);
240 tmp2 := MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865);
242 tmp10 := tmp0 + tmp2;
243 tmp12 := tmp0 - tmp2;
245 { Odd part }
247 z1 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*7]) * quantptr^[DCTSIZE*7];
248 z2 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*5]) * quantptr^[DCTSIZE*5];
249 z3 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*3]) * quantptr^[DCTSIZE*3];
250 z4 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*1]) * quantptr^[DCTSIZE*1];
252 tmp0 := MULTIPLY(z1, - FIX_0_211164243) { sqrt(2) * (c3-c1) }
253 + MULTIPLY(z2, FIX_1_451774981) { sqrt(2) * (c3+c7) }
254 + MULTIPLY(z3, - FIX_2_172734803) { sqrt(2) * (-c1-c5) }
255 + MULTIPLY(z4, FIX_1_061594337); { sqrt(2) * (c5+c7) }
257 tmp2 := MULTIPLY(z1, - FIX_0_509795579) { sqrt(2) * (c7-c5) }
258 + MULTIPLY(z2, - FIX_0_601344887) { sqrt(2) * (c5-c1) }
259 + MULTIPLY(z3, FIX_0_899976223) { sqrt(2) * (c3-c7) }
260 + MULTIPLY(z4, FIX_2_562915447); { sqrt(2) * (c1+c3) }
262 { Final output stage }
264 wsptr^[DCTSIZE*0] := int(DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1));
265 wsptr^[DCTSIZE*3] := int(DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1));
266 wsptr^[DCTSIZE*1] := int(DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1));
267 wsptr^[DCTSIZE*2] := int(DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1));
269 Inc(JCOEF_PTR(inptr));
270 Inc(ISLOW_MULT_TYPE_PTR(quantptr));
271 Inc(int_ptr(wsptr));
272 end;
274 { Pass 2: process 4 rows from work array, store into output array. }
276 wsptr := @workspace;
277 for ctr := 0 to pred(4) do
278 begin
279 outptr := JSAMPROW(@ output_buf^[ctr]^[output_col]);
280 { It's not clear whether a zero row test is worthwhile here ... }
282 {$ifndef NO_ZERO_ROW_TEST}
283 if (wsptr^[1]=0) and (wsptr^[2]=0) and (wsptr^[3]=0) and
284 (wsptr^[5]=0) and (wsptr^[6]=0) and (wsptr^[7]=0) then
285 begin
286 { AC terms all zero }
287 dcval_ := range_limit^[int(DESCALE(INT32(wsptr^[0]), PASS1_BITS+3))
288 and RANGE_MASK];
290 outptr^[0] := dcval_;
291 outptr^[1] := dcval_;
292 outptr^[2] := dcval_;
293 outptr^[3] := dcval_;
295 Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row }
296 continue;
297 end;
298 {$endif}
300 { Even part }
302 tmp0 := (INT32(wsptr^[0])) shl (CONST_BITS+1);
304 tmp2 := MULTIPLY(INT32(wsptr^[2]), FIX_1_847759065)
305 + MULTIPLY(INT32(wsptr^[6]), - FIX_0_765366865);
307 tmp10 := tmp0 + tmp2;
308 tmp12 := tmp0 - tmp2;
310 { Odd part }
312 z1 := INT32(wsptr^[7]);
313 z2 := INT32(wsptr^[5]);
314 z3 := INT32(wsptr^[3]);
315 z4 := INT32(wsptr^[1]);
317 tmp0 := MULTIPLY(z1, - FIX_0_211164243) { sqrt(2) * (c3-c1) }
318 + MULTIPLY(z2, FIX_1_451774981) { sqrt(2) * (c3+c7) }
319 + MULTIPLY(z3, - FIX_2_172734803) { sqrt(2) * (-c1-c5) }
320 + MULTIPLY(z4, FIX_1_061594337); { sqrt(2) * (c5+c7) }
322 tmp2 := MULTIPLY(z1, - FIX_0_509795579) { sqrt(2) * (c7-c5) }
323 + MULTIPLY(z2, - FIX_0_601344887) { sqrt(2) * (c5-c1) }
324 + MULTIPLY(z3, FIX_0_899976223) { sqrt(2) * (c3-c7) }
325 + MULTIPLY(z4, FIX_2_562915447); { sqrt(2) * (c1+c3) }
327 { Final output stage }
329 outptr^[0] := range_limit^[ int(DESCALE(tmp10 + tmp2,
330 CONST_BITS+PASS1_BITS+3+1))
331 and RANGE_MASK];
332 outptr^[3] := range_limit^[ int(DESCALE(tmp10 - tmp2,
333 CONST_BITS+PASS1_BITS+3+1))
334 and RANGE_MASK];
335 outptr^[1] := range_limit^[ int(DESCALE(tmp12 + tmp0,
336 CONST_BITS+PASS1_BITS+3+1))
337 and RANGE_MASK];
338 outptr^[2] := range_limit^[ int(DESCALE(tmp12 - tmp0,
339 CONST_BITS+PASS1_BITS+3+1))
340 and RANGE_MASK];
342 Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row }
343 end;
344 end;
347 { Perform dequantization and inverse DCT on one block of coefficients,
348 producing a reduced-size 2x2 output block. }
350 {GLOBAL}
351 procedure jpeg_idct_2x2 (cinfo : j_decompress_ptr;
352 compptr : jpeg_component_info_ptr;
353 coef_block : JCOEFPTR;
354 output_buf : JSAMPARRAY;
355 output_col : JDIMENSION);
356 type
357 PWorkspace = ^TWorkspace;
358 TWorkspace = array[0..(DCTSIZE*2)-1] of int; { buffers data between passes }
359 var
360 tmp0, tmp10, z1 : INT32;
361 inptr : JCOEFPTR;
362 quantptr : ISLOW_MULT_TYPE_FIELD_PTR;
363 wsptr : PWorkspace;
364 outptr : JSAMPROW;
365 range_limit : JSAMPROW;
366 ctr : int;
367 workspace : TWorkspace; { buffers data between passes }
368 {SHIFT_TEMPS}
369 var
370 dcval : int;
371 var
372 dcval_ : JSAMPLE;
373 begin
374 { Each IDCT routine is responsible for range-limiting its results and
375 converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could
376 be quite far out of range if the input data is corrupt, so a bulletproof
377 range-limiting step is required. We use a mask-and-table-lookup method
378 to do the combined operations quickly. See the comments with
379 prepare_range_limit_table (in jdmaster.c) for more info. }
381 range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE]));
382 { Pass 1: process columns from input, store into work array. }
384 inptr := coef_block;
385 quantptr := ISLOW_MULT_TYPE_FIELD_PTR (compptr^.dct_table);
386 wsptr := @workspace;
387 for ctr := DCTSIZE downto 1 do
388 begin
389 { Don't bother to process columns 2,4,6 }
390 if (ctr = DCTSIZE-2) or (ctr = DCTSIZE-4) or (ctr = DCTSIZE-6) then
391 begin
392 Inc(JCOEF_PTR(inptr));
393 Inc(ISLOW_MULT_TYPE_PTR(quantptr));
394 Inc(int_ptr(wsptr));
396 continue;
397 end;
398 if (inptr^[DCTSIZE*1]=0) and (inptr^[DCTSIZE*3]=0) and
399 (inptr^[DCTSIZE*5]=0) and (inptr^[DCTSIZE*7]=0) then
400 begin
401 { AC terms all zero; we need not examine terms 2,4,6 for 2x2 output }
402 dcval := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*0]) *
403 quantptr^[DCTSIZE*0]) shl PASS1_BITS;
405 wsptr^[DCTSIZE*0] := dcval;
406 wsptr^[DCTSIZE*1] := dcval;
408 Inc(JCOEF_PTR(inptr));
409 Inc(ISLOW_MULT_TYPE_PTR(quantptr));
410 Inc(int_ptr(wsptr));
412 continue;
413 end;
415 { Even part }
417 z1 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*0]) * quantptr^[DCTSIZE*0]);
419 tmp10 := z1 shl (CONST_BITS+2);
421 { Odd part }
423 z1 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*7]) * quantptr^[DCTSIZE*7]);
424 tmp0 := MULTIPLY(z1, - FIX_0_720959822); { sqrt(2) * (c7-c5+c3-c1) }
425 z1 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*5]) * quantptr^[DCTSIZE*5]);
426 Inc(tmp0, MULTIPLY(z1, FIX_0_850430095)); { sqrt(2) * (-c1+c3+c5+c7) }
427 z1 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*3]) * quantptr^[DCTSIZE*3]);
428 Inc(tmp0, MULTIPLY(z1, - FIX_1_272758580)); { sqrt(2) * (-c1+c3-c5-c7) }
429 z1 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*1]) * quantptr^[DCTSIZE*1]);
430 Inc(tmp0, MULTIPLY(z1, FIX_3_624509785)); { sqrt(2) * (c1+c3+c5+c7) }
432 { Final output stage }
434 wsptr^[DCTSIZE*0] := int (DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2));
435 wsptr^[DCTSIZE*1] := int (DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2));
437 Inc(JCOEF_PTR(inptr));
438 Inc(ISLOW_MULT_TYPE_PTR(quantptr));
439 Inc(int_ptr(wsptr));
440 end;
442 { Pass 2: process 2 rows from work array, store into output array. }
444 wsptr := @workspace;
445 for ctr := 0 to pred(2) do
446 begin
447 outptr := JSAMPROW(@ output_buf^[ctr]^[output_col]);
448 { It's not clear whether a zero row test is worthwhile here ... }
450 {$ifndef NO_ZERO_ROW_TEST}
451 if (wsptr^[1]=0) and (wsptr^[3]=0) and (wsptr^[5]=0) and (wsptr^[7]= 0) then
452 begin
453 { AC terms all zero }
454 dcval_ := range_limit^[ int(DESCALE(INT32(wsptr^[0]), PASS1_BITS+3))
455 and RANGE_MASK];
457 outptr^[0] := dcval_;
458 outptr^[1] := dcval_;
460 Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row }
461 continue;
462 end;
463 {$endif}
465 { Even part }
467 tmp10 := (INT32 (wsptr^[0])) shl (CONST_BITS+2);
469 { Odd part }
471 tmp0 := MULTIPLY( INT32(wsptr^[7]), - FIX_0_720959822) { sqrt(2) * (c7-c5+c3-c1) }
472 + MULTIPLY( INT32(wsptr^[5]), FIX_0_850430095) { sqrt(2) * (-c1+c3+c5+c7) }
473 + MULTIPLY( INT32(wsptr^[3]), - FIX_1_272758580) { sqrt(2) * (-c1+c3-c5-c7) }
474 + MULTIPLY( INT32(wsptr^[1]), FIX_3_624509785); { sqrt(2) * (c1+c3+c5+c7) }
476 { Final output stage }
478 outptr^[0] := range_limit^[ int(DESCALE(tmp10 + tmp0,
479 CONST_BITS+PASS1_BITS+3+2))
480 and RANGE_MASK];
481 outptr^[1] := range_limit^[ int(DESCALE(tmp10 - tmp0,
482 CONST_BITS+PASS1_BITS+3+2))
483 and RANGE_MASK];
485 Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row }
486 end;
487 end;
490 { Perform dequantization and inverse DCT on one block of coefficients,
491 producing a reduced-size 1x1 output block. }
493 {GLOBAL}
494 procedure jpeg_idct_1x1 (cinfo : j_decompress_ptr;
495 compptr : jpeg_component_info_ptr;
496 coef_block : JCOEFPTR;
497 output_buf : JSAMPARRAY;
498 output_col : JDIMENSION);
499 var
500 dcval : int;
501 quantptr : ISLOW_MULT_TYPE_FIELD_PTR;
502 range_limit : JSAMPROW;
503 {SHIFT_TEMPS}
504 begin
505 { Each IDCT routine is responsible for range-limiting its results and
506 converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could
507 be quite far out of range if the input data is corrupt, so a bulletproof
508 range-limiting step is required. We use a mask-and-table-lookup method
509 to do the combined operations quickly. See the comments with
510 prepare_range_limit_table (in jdmaster.c) for more info. }
512 range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE]));
513 { Pass 1: process columns from input, store into work array. }
515 { We hardly need an inverse DCT routine for this: just take the
516 average pixel value, which is one-eighth of the DC coefficient. }
518 quantptr := ISLOW_MULT_TYPE_FIELD_PTR (compptr^.dct_table);
519 dcval := (ISLOW_MULT_TYPE(coef_block^[0]) * quantptr^[0]);
520 dcval := int (DESCALE( INT32(dcval), 3));
522 output_buf^[0]^[output_col] := range_limit^[dcval and RANGE_MASK];
523 end;
525 end.