DEADSOFTWARE

hopefully no more windows
[d2df-editor.git] / src / lib / vampimg / JpegLib / imjcsample.pas
1 unit imjcsample;
3 { This file contains downsampling routines.
5 Downsampling input data is counted in "row groups". A row group
6 is defined to be max_v_samp_factor pixel rows of each component,
7 from which the downsampler produces v_samp_factor sample rows.
8 A single row group is processed in each call to the downsampler module.
10 The downsampler is responsible for edge-expansion of its output data
11 to fill an integral number of DCT blocks horizontally. The source buffer
12 may be modified if it is helpful for this purpose (the source buffer is
13 allocated wide enough to correspond to the desired output width).
14 The caller (the prep controller) is responsible for vertical padding.
16 The downsampler may request "context rows" by setting need_context_rows
17 during startup. In this case, the input arrays will contain at least
18 one row group's worth of pixels above and below the passed-in data;
19 the caller will create dummy rows at image top and bottom by replicating
20 the first or last real pixel row.
22 An excellent reference for image resampling is
23 Digital Image Warping, George Wolberg, 1990.
24 Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
26 The downsampling algorithm used here is a simple average of the source
27 pixels covered by the output pixel. The hi-falutin sampling literature
28 refers to this as a "box filter". In general the characteristics of a box
29 filter are not very good, but for the specific cases we normally use (1:1
30 and 2:1 ratios) the box is equivalent to a "triangle filter" which is not
31 nearly so bad. If you intend to use other sampling ratios, you'd be well
32 advised to improve this code.
34 A simple input-smoothing capability is provided. This is mainly intended
35 for cleaning up color-dithered GIF input files (if you find it inadequate,
36 we suggest using an external filtering program such as pnmconvol). When
37 enabled, each input pixel P is replaced by a weighted sum of itself and its
38 eight neighbors. P's weight is 1-8*SF and each neighbor's weight is SF,
39 where SF := (smoothing_factor / 1024).
40 Currently, smoothing is only supported for 2h2v sampling factors. }
42 { Original: jcsample.c ; Copyright (C) 1991-1996, Thomas G. Lane. }
45 interface
47 {$I imjconfig.inc}
49 uses
50 imjmorecfg,
51 imjinclude,
52 imjutils,
53 imjdeferr,
54 imjerror,
55 imjpeglib;
58 { Module initialization routine for downsampling.
59 Note that we must select a routine for each component. }
61 {GLOBAL}
62 procedure jinit_downsampler (cinfo : j_compress_ptr);
64 implementation
66 { Pointer to routine to downsample a single component }
67 type
68 downsample1_ptr = procedure(cinfo : j_compress_ptr;
69 compptr : jpeg_component_info_ptr;
70 input_data : JSAMPARRAY;
71 output_data : JSAMPARRAY);
73 { Private subobject }
75 type
76 my_downsample_ptr = ^my_downsampler;
77 my_downsampler = record
78 pub : jpeg_downsampler; { public fields }
80 { Downsampling method pointers, one per component }
81 methods : array[0..MAX_COMPONENTS-1] of downsample1_ptr;
82 end;
84 { Initialize for a downsampling pass. }
86 {METHODDEF}
87 procedure start_pass_downsample (cinfo : j_compress_ptr);
88 begin
89 { no work for now }
90 end;
93 { Expand a component horizontally from width input_cols to width output_cols,
94 by duplicating the rightmost samples. }
96 {LOCAL}
97 procedure expand_right_edge (image_data : JSAMPARRAY;
98 num_rows : int;
99 input_cols : JDIMENSION;
100 output_cols : JDIMENSION);
101 var
102 {register} ptr : JSAMPLE_PTR;
103 {register} pixval : JSAMPLE;
104 {register} count : int;
105 row : int;
106 numcols : int;
107 begin
108 numcols := int (output_cols - input_cols);
110 if (numcols > 0) then
111 begin
112 for row := 0 to pred(num_rows) do
113 begin
114 ptr := JSAMPLE_PTR(@(image_data^[row]^[input_cols-1]));
115 pixval := ptr^; { don't need GETJSAMPLE() here }
116 for count := pred(numcols) downto 0 do
117 begin
118 Inc(ptr);
119 ptr^ := pixval;
120 end;
121 end;
122 end;
123 end;
126 { Do downsampling for a whole row group (all components).
128 In this version we simply downsample each component independently. }
130 {METHODDEF}
131 procedure sep_downsample (cinfo : j_compress_ptr;
132 input_buf : JSAMPIMAGE;
133 in_row_index : JDIMENSION;
134 output_buf : JSAMPIMAGE;
135 out_row_group_index : JDIMENSION);
136 var
137 downsample : my_downsample_ptr;
138 ci : int;
139 compptr : jpeg_component_info_ptr;
140 in_ptr, out_ptr : JSAMPARRAY;
141 begin
142 downsample := my_downsample_ptr (cinfo^.downsample);
144 compptr := jpeg_component_info_ptr(cinfo^.comp_info);
145 for ci := 0 to pred(cinfo^.num_components) do
146 begin
147 in_ptr := JSAMPARRAY(@ input_buf^[ci]^[in_row_index]);
148 out_ptr := JSAMPARRAY(@ output_buf^[ci]^
149 [out_row_group_index * JDIMENSION(compptr^.v_samp_factor)]);
150 downsample^.methods[ci] (cinfo, compptr, in_ptr, out_ptr);
151 Inc(compptr);
152 end;
153 end;
156 { Downsample pixel values of a single component.
157 One row group is processed per call.
158 This version handles arbitrary integral sampling ratios, without smoothing.
159 Note that this version is not actually used for customary sampling ratios. }
161 {METHODDEF}
162 procedure int_downsample (cinfo : j_compress_ptr;
163 compptr : jpeg_component_info_ptr;
164 input_data : JSAMPARRAY;
165 output_data : JSAMPARRAY);
166 var
167 inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v : int;
168 outcol, outcol_h : JDIMENSION; { outcol_h = outcol*h_expand }
169 output_cols : JDIMENSION;
170 inptr,
171 outptr : JSAMPLE_PTR;
172 outvalue : INT32;
173 begin
174 output_cols := compptr^.width_in_blocks * DCTSIZE;
176 h_expand := cinfo^.max_h_samp_factor div compptr^.h_samp_factor;
177 v_expand := cinfo^.max_v_samp_factor div compptr^.v_samp_factor;
178 numpix := h_expand * v_expand;
179 numpix2 := numpix div 2;
181 { Expand input data enough to let all the output samples be generated
182 by the standard loop. Special-casing padded output would be more
183 efficient. }
185 expand_right_edge(input_data, cinfo^.max_v_samp_factor,
186 cinfo^.image_width, output_cols * JDIMENSION(h_expand));
188 inrow := 0;
189 for outrow := 0 to pred(compptr^.v_samp_factor) do
190 begin
191 outptr := JSAMPLE_PTR(output_data^[outrow]);
192 outcol_h := 0;
193 for outcol := 0 to pred(output_cols) do
194 begin
195 outvalue := 0;
196 for v := 0 to pred(v_expand) do
197 begin
198 inptr := @(input_data^[inrow+v]^[outcol_h]);
199 for h := 0 to pred(h_expand) do
200 begin
201 Inc(outvalue, INT32 (GETJSAMPLE(inptr^)) );
202 Inc(inptr);
203 end;
204 end;
205 outptr^ := JSAMPLE ((outvalue + numpix2) div numpix);
206 Inc(outptr);
207 Inc(outcol_h, h_expand);
208 end;
209 Inc(inrow, v_expand);
210 end;
211 end;
214 { Downsample pixel values of a single component.
215 This version handles the special case of a full-size component,
216 without smoothing. }
218 {METHODDEF}
219 procedure fullsize_downsample (cinfo : j_compress_ptr;
220 compptr : jpeg_component_info_ptr;
221 input_data : JSAMPARRAY;
222 output_data : JSAMPARRAY);
223 begin
224 { Copy the data }
225 jcopy_sample_rows(input_data, 0, output_data, 0,
226 cinfo^.max_v_samp_factor, cinfo^.image_width);
227 { Edge-expand }
228 expand_right_edge(output_data, cinfo^.max_v_samp_factor,
229 cinfo^.image_width, compptr^.width_in_blocks * DCTSIZE);
230 end;
233 { Downsample pixel values of a single component.
234 This version handles the common case of 2:1 horizontal and 1:1 vertical,
235 without smoothing.
237 A note about the "bias" calculations: when rounding fractional values to
238 integer, we do not want to always round 0.5 up to the next integer.
239 If we did that, we'd introduce a noticeable bias towards larger values.
240 Instead, this code is arranged so that 0.5 will be rounded up or down at
241 alternate pixel locations (a simple ordered dither pattern). }
243 {METHODDEF}
244 procedure h2v1_downsample (cinfo : j_compress_ptr;
245 compptr : jpeg_component_info_ptr;
246 input_data : JSAMPARRAY;
247 output_data : JSAMPARRAY);
248 var
249 outrow : int;
250 outcol : JDIMENSION;
251 output_cols : JDIMENSION;
252 {register} inptr, outptr : JSAMPLE_PTR;
253 {register} bias : int;
254 begin
255 output_cols := compptr^.width_in_blocks * DCTSIZE;
257 { Expand input data enough to let all the output samples be generated
258 by the standard loop. Special-casing padded output would be more
259 efficient. }
261 expand_right_edge(input_data, cinfo^.max_v_samp_factor,
262 cinfo^.image_width, output_cols * 2);
264 for outrow := 0 to pred(compptr^.v_samp_factor) do
265 begin
266 outptr := JSAMPLE_PTR(output_data^[outrow]);
267 inptr := JSAMPLE_PTR(input_data^[outrow]);
268 bias := 0; { bias := 0,1,0,1,... for successive samples }
269 for outcol := 0 to pred(output_cols) do
270 begin
271 outptr^ := JSAMPLE ((GETJSAMPLE(inptr^) +
272 GETJSAMPLE(JSAMPROW(inptr)^[1]) + bias) shr 1);
273 Inc(outptr);
274 bias := bias xor 1; { 0=>1, 1=>0 }
275 Inc(inptr, 2);
276 end;
277 end;
278 end;
281 { Downsample pixel values of a single component.
282 This version handles the standard case of 2:1 horizontal and 2:1 vertical,
283 without smoothing. }
285 {METHODDEF}
286 procedure h2v2_downsample (cinfo : j_compress_ptr;
287 compptr : jpeg_component_info_ptr;
288 input_data : JSAMPARRAY;
289 output_data : JSAMPARRAY);
290 var
291 inrow, outrow : int;
292 outcol : JDIMENSION;
293 output_cols : JDIMENSION;
294 {register} inptr0, inptr1, outptr : JSAMPLE_PTR;
295 {register} bias : int;
296 begin
297 output_cols := compptr^.width_in_blocks * DCTSIZE;
299 { Expand input data enough to let all the output samples be generated
300 by the standard loop. Special-casing padded output would be more
301 efficient. }
303 expand_right_edge(input_data, cinfo^.max_v_samp_factor,
304 cinfo^.image_width, output_cols * 2);
306 inrow := 0;
307 for outrow := 0 to pred(compptr^.v_samp_factor) do
308 begin
309 outptr := JSAMPLE_PTR(output_data^[outrow]);
310 inptr0 := JSAMPLE_PTR(input_data^[inrow]);
311 inptr1 := JSAMPLE_PTR(input_data^[inrow+1]);
312 bias := 1; { bias := 1,2,1,2,... for successive samples }
313 for outcol := 0 to pred(output_cols) do
314 begin
315 outptr^ := JSAMPLE ((GETJSAMPLE(inptr0^) +
316 GETJSAMPLE(JSAMPROW(inptr0)^[1]) +
317 GETJSAMPLE(inptr1^) +
318 GETJSAMPLE(JSAMPROW(inptr1)^[1]) + bias) shr 2);
319 Inc(outptr);
320 bias := bias xor 3; { 1=>2, 2=>1 }
321 Inc(inptr0, 2);
322 Inc(inptr1, 2);
323 end;
324 Inc(inrow, 2);
325 end;
326 end;
329 {$ifdef INPUT_SMOOTHING_SUPPORTED}
331 { Downsample pixel values of a single component.
332 This version handles the standard case of 2:1 horizontal and 2:1 vertical,
333 with smoothing. One row of context is required. }
335 {METHODDEF}
336 procedure h2v2_smooth_downsample (cinfo : j_compress_ptr;
337 compptr : jpeg_component_info_ptr;
338 input_data : JSAMPARRAY;
339 output_data : JSAMPARRAY);
340 var
341 inrow, outrow : int;
342 colctr : JDIMENSION;
343 output_cols : JDIMENSION;
344 {register} inptr0, inptr1, above_ptr, below_ptr, outptr : JSAMPLE_PTR;
345 membersum, neighsum, memberscale, neighscale : INT32;
346 var
347 prev_input_data : JSAMPARRAY;
348 prev_inptr0, prev_inptr1, prev_above_ptr, prev_below_ptr : JSAMPLE_PTR;
349 begin
350 output_cols := compptr^.width_in_blocks * DCTSIZE;
352 { Expand input data enough to let all the output samples be generated
353 by the standard loop. Special-casing padded output would be more
354 efficient. }
356 prev_input_data := input_data;
357 Dec(JSAMPROW_PTR(prev_input_data));
358 expand_right_edge(prev_input_data, cinfo^.max_v_samp_factor + 2,
359 cinfo^.image_width, output_cols * 2);
361 { We don't bother to form the individual "smoothed" input pixel values;
362 we can directly compute the output which is the average of the four
363 smoothed values. Each of the four member pixels contributes a fraction
364 (1-8*SF) to its own smoothed image and a fraction SF to each of the three
365 other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final
366 output. The four corner-adjacent neighbor pixels contribute a fraction
367 SF to just one smoothed pixel, or SF/4 to the final output; while the
368 eight edge-adjacent neighbors contribute SF to each of two smoothed
369 pixels, or SF/2 overall. In order to use integer arithmetic, these
370 factors are scaled by 2^16 := 65536.
371 Also recall that SF := smoothing_factor / 1024. }
373 memberscale := 16384 - cinfo^.smoothing_factor * 80; { scaled (1-5*SF)/4 }
374 neighscale := cinfo^.smoothing_factor * 16; { scaled SF/4 }
376 inrow := 0;
377 for outrow := 0 to pred(compptr^.v_samp_factor) do
378 begin
379 outptr := JSAMPLE_PTR(output_data^[outrow]);
380 inptr0 := JSAMPLE_PTR(input_data^[inrow]);
381 inptr1 := JSAMPLE_PTR(input_data^[inrow+1]);
382 above_ptr := JSAMPLE_PTR(input_data^[inrow-1]);
383 below_ptr := JSAMPLE_PTR(input_data^[inrow+2]);
385 { Special case for first column: pretend column -1 is same as column 0 }
386 membersum := GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) +
387 GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]);
388 neighsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(JSAMPROW(above_ptr)^[1]) +
389 GETJSAMPLE(below_ptr^) + GETJSAMPLE(JSAMPROW(below_ptr)^[1]) +
390 GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[2]) +
391 GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[2]);
392 Inc(neighsum, neighsum);
393 Inc(neighsum, GETJSAMPLE(above_ptr^) +
394 GETJSAMPLE(JSAMPROW(above_ptr)^[2]) +
395 GETJSAMPLE(below_ptr^) +
396 GETJSAMPLE(JSAMPROW(below_ptr)^[2]) );
397 membersum := membersum * memberscale + neighsum * neighscale;
398 outptr^ := JSAMPLE ((membersum + 32768) shr 16);
399 Inc(outptr);
400 prev_inptr0 := inptr0;
401 prev_inptr1 := inptr1;
402 Inc(prev_inptr0);
403 Inc(prev_inptr1);
404 Inc(inptr0, 2);
405 Inc(inptr1, 2);
406 prev_above_ptr := above_ptr;
407 prev_below_ptr := below_ptr;
408 Inc(above_ptr, 2);
409 Inc(below_ptr, 2);
410 Inc(prev_above_ptr, 1);
411 Inc(prev_below_ptr, 1);
413 for colctr := pred(output_cols - 2) downto 0 do
414 begin
415 { sum of pixels directly mapped to this output element }
416 membersum := GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) +
417 GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]);
418 { sum of edge-neighbor pixels }
419 neighsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(JSAMPROW(above_ptr)^[1]) +
420 GETJSAMPLE(below_ptr^) + GETJSAMPLE(JSAMPROW(below_ptr)^[1]) +
421 GETJSAMPLE(prev_inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[2]) +
422 GETJSAMPLE(prev_inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[2]);
423 { The edge-neighbors count twice as much as corner-neighbors }
424 Inc(neighsum, neighsum);
425 { Add in the corner-neighbors }
426 Inc(neighsum, GETJSAMPLE(prev_above_ptr^) +
427 GETJSAMPLE(JSAMPROW(above_ptr)^[2]) +
428 GETJSAMPLE(prev_below_ptr^) +
429 GETJSAMPLE(JSAMPROW(below_ptr)^[2]) );
430 { form final output scaled up by 2^16 }
431 membersum := membersum * memberscale + neighsum * neighscale;
432 { round, descale and output it }
433 outptr^ := JSAMPLE ((membersum + 32768) shr 16);
434 Inc(outptr);
435 Inc(inptr0, 2);
436 Inc(inptr1, 2);
437 Inc(prev_inptr0, 2);
438 Inc(prev_inptr1, 2);
439 Inc(above_ptr, 2);
440 Inc(below_ptr, 2);
441 Inc(prev_above_ptr, 2);
442 Inc(prev_below_ptr, 2);
443 end;
445 { Special case for last column }
446 membersum := GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) +
447 GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]);
448 neighsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(JSAMPROW(above_ptr)^[1]) +
449 GETJSAMPLE(below_ptr^) + GETJSAMPLE(JSAMPROW(below_ptr)^[1]) +
450 GETJSAMPLE(prev_inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) +
451 GETJSAMPLE(prev_inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]);
452 Inc(neighsum, neighsum);
453 Inc(neighsum, GETJSAMPLE(prev_above_ptr^) +
454 GETJSAMPLE(JSAMPROW(above_ptr)^[1]) +
455 GETJSAMPLE(prev_below_ptr^) +
456 GETJSAMPLE(JSAMPROW(below_ptr)^[1]) );
457 membersum := membersum * memberscale + neighsum * neighscale;
458 outptr^ := JSAMPLE ((membersum + 32768) shr 16);
460 Inc(inrow, 2);
461 end;
462 end;
465 { Downsample pixel values of a single component.
466 This version handles the special case of a full-size component,
467 with smoothing. One row of context is required. }
469 {METHODDEF}
470 procedure fullsize_smooth_downsample (cinfo : j_compress_ptr;
471 compptr : jpeg_component_info_ptr;
472 input_data : JSAMPARRAY;
473 output_data : JSAMPARRAY);
474 var
475 outrow : int;
476 colctr : JDIMENSION;
477 output_cols : JDIMENSION;
478 {register} inptr, above_ptr, below_ptr, outptr : JSAMPLE_PTR;
479 membersum, neighsum, memberscale, neighscale : INT32;
480 colsum, lastcolsum, nextcolsum : int;
481 var
482 prev_input_data : JSAMPARRAY;
483 begin
484 output_cols := compptr^.width_in_blocks * DCTSIZE;
486 { Expand input data enough to let all the output samples be generated
487 by the standard loop. Special-casing padded output would be more
488 efficient. }
490 prev_input_data := input_data;
491 Dec(JSAMPROW_PTR(prev_input_data));
492 expand_right_edge(prev_input_data, cinfo^.max_v_samp_factor + 2,
493 cinfo^.image_width, output_cols);
495 { Each of the eight neighbor pixels contributes a fraction SF to the
496 smoothed pixel, while the main pixel contributes (1-8*SF). In order
497 to use integer arithmetic, these factors are multiplied by 2^16 := 65536.
498 Also recall that SF := smoothing_factor / 1024. }
500 memberscale := long(65536) - cinfo^.smoothing_factor * long(512); { scaled 1-8*SF }
501 neighscale := cinfo^.smoothing_factor * 64; { scaled SF }
503 for outrow := 0 to pred(compptr^.v_samp_factor) do
504 begin
505 outptr := JSAMPLE_PTR(output_data^[outrow]);
506 inptr := JSAMPLE_PTR(input_data^[outrow]);
507 above_ptr := JSAMPLE_PTR(input_data^[outrow-1]);
508 below_ptr := JSAMPLE_PTR(input_data^[outrow+1]);
510 { Special case for first column }
511 colsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(below_ptr^) +
512 GETJSAMPLE(inptr^);
513 Inc(above_ptr);
514 Inc(below_ptr);
515 membersum := GETJSAMPLE(inptr^);
516 Inc(inptr);
517 nextcolsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(below_ptr^) +
518 GETJSAMPLE(inptr^);
519 neighsum := colsum + (colsum - membersum) + nextcolsum;
520 membersum := membersum * memberscale + neighsum * neighscale;
521 outptr^ := JSAMPLE ((membersum + 32768) shr 16);
522 Inc(outptr);
523 lastcolsum := colsum; colsum := nextcolsum;
525 for colctr := pred(output_cols - 2) downto 0 do
526 begin
527 membersum := GETJSAMPLE(inptr^);
528 Inc(inptr);
529 Inc(above_ptr);
530 Inc(below_ptr);
531 nextcolsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(below_ptr^) +
532 GETJSAMPLE(inptr^);
533 neighsum := lastcolsum + (colsum - membersum) + nextcolsum;
534 membersum := membersum * memberscale + neighsum * neighscale;
535 outptr^ := JSAMPLE ((membersum + 32768) shr 16);
536 Inc(outptr);
537 lastcolsum := colsum; colsum := nextcolsum;
538 end;
540 { Special case for last column }
541 membersum := GETJSAMPLE(inptr^);
542 neighsum := lastcolsum + (colsum - membersum) + colsum;
543 membersum := membersum * memberscale + neighsum * neighscale;
544 outptr^ := JSAMPLE ((membersum + 32768) shr 16);
545 end;
546 end;
548 {$endif} { INPUT_SMOOTHING_SUPPORTED }
551 { Module initialization routine for downsampling.
552 Note that we must select a routine for each component. }
554 {GLOBAL}
555 procedure jinit_downsampler (cinfo : j_compress_ptr);
556 var
557 downsample : my_downsample_ptr;
558 ci : int;
559 compptr : jpeg_component_info_ptr;
560 smoothok : boolean;
561 begin
562 smoothok := TRUE;
564 downsample := my_downsample_ptr(
565 cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
566 SIZEOF(my_downsampler)) );
567 cinfo^.downsample := jpeg_downsampler_ptr (downsample);
568 downsample^.pub.start_pass := start_pass_downsample;
569 downsample^.pub.downsample := sep_downsample;
570 downsample^.pub.need_context_rows := FALSE;
572 if (cinfo^.CCIR601_sampling) then
573 ERREXIT(j_common_ptr(cinfo), JERR_CCIR601_NOTIMPL);
575 { Verify we can handle the sampling factors, and set up method pointers }
576 compptr := jpeg_component_info_ptr(cinfo^.comp_info);
577 for ci := 0 to pred(cinfo^.num_components) do
578 begin
579 if (compptr^.h_samp_factor = cinfo^.max_h_samp_factor) and
580 (compptr^.v_samp_factor = cinfo^.max_v_samp_factor) then
581 begin
582 {$ifdef INPUT_SMOOTHING_SUPPORTED}
583 if (cinfo^.smoothing_factor <> 0) then
584 begin
585 downsample^.methods[ci] := fullsize_smooth_downsample;
586 downsample^.pub.need_context_rows := TRUE;
587 end
588 else
589 {$endif}
590 downsample^.methods[ci] := fullsize_downsample;
591 end
592 else
593 if (compptr^.h_samp_factor * 2 = cinfo^.max_h_samp_factor) and
594 (compptr^.v_samp_factor = cinfo^.max_v_samp_factor) then
595 begin
596 smoothok := FALSE;
597 downsample^.methods[ci] := h2v1_downsample;
598 end
599 else
600 if (compptr^.h_samp_factor * 2 = cinfo^.max_h_samp_factor) and
601 (compptr^.v_samp_factor * 2 = cinfo^.max_v_samp_factor) then
602 begin
603 {$ifdef INPUT_SMOOTHING_SUPPORTED}
604 if (cinfo^.smoothing_factor <> 0) then
605 begin
606 downsample^.methods[ci] := h2v2_smooth_downsample;
607 downsample^.pub.need_context_rows := TRUE;
608 end
609 else
610 {$endif}
611 downsample^.methods[ci] := h2v2_downsample;
612 end
613 else
614 if ((cinfo^.max_h_samp_factor mod compptr^.h_samp_factor) = 0) and
615 ((cinfo^.max_v_samp_factor mod compptr^.v_samp_factor) = 0) then
616 begin
617 smoothok := FALSE;
618 downsample^.methods[ci] := int_downsample;
619 end
620 else
621 ERREXIT(j_common_ptr(cinfo), JERR_FRACT_SAMPLE_NOTIMPL);
622 Inc(compptr);
623 end;
625 {$ifdef INPUT_SMOOTHING_SUPPORTED}
626 if (cinfo^.smoothing_factor <> 0) and (not smoothok) then
627 TRACEMS(j_common_ptr(cinfo), 0, JTRC_SMOOTH_NOTIMPL);
628 {$endif}
629 end;
631 end.