📄 jcsample.pas
字号:
GETJSAMPLE(inptr1^) +
GETJSAMPLE(JSAMPROW(inptr1)^[1]) + bias) shr 2);
Inc(outptr);
bias := bias xor 3; { 1=>2, 2=>1 }
Inc(inptr0, 2);
Inc(inptr1, 2);
end;
Inc(inrow, 2);
end;
end;
{$ifdef INPUT_SMOOTHING_SUPPORTED}
{ Downsample pixel values of a single component.
This version handles the standard case of 2:1 horizontal and 2:1 vertical,
with smoothing. One row of context is required. }
{METHODDEF}
procedure h2v2_smooth_downsample (cinfo : j_compress_ptr;
compptr : jpeg_component_info_ptr;
input_data : JSAMPARRAY;
output_data : JSAMPARRAY); far;
var
inrow, outrow : int;
colctr : JDIMENSION;
output_cols : JDIMENSION;
{register} inptr0, inptr1, above_ptr, below_ptr, outptr : JSAMPLE_PTR;
membersum, neighsum, memberscale, neighscale : INT32;
var
prev_input_data : JSAMPARRAY;
prev_inptr0, prev_inptr1, prev_above_ptr, prev_below_ptr : JSAMPLE_PTR;
begin
output_cols := compptr^.width_in_blocks * DCTSIZE;
{ Expand input data enough to let all the output samples be generated
by the standard loop. Special-casing padded output would be more
efficient. }
prev_input_data := input_data;
Dec(JSAMPROW_PTR(prev_input_data));
expand_right_edge(prev_input_data, cinfo^.max_v_samp_factor + 2,
cinfo^.image_width, output_cols * 2);
{ We don't bother to form the individual "smoothed" input pixel values;
we can directly compute the output which is the average of the four
smoothed values. Each of the four member pixels contributes a fraction
(1-8*SF) to its own smoothed image and a fraction SF to each of the three
other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final
output. The four corner-adjacent neighbor pixels contribute a fraction
SF to just one smoothed pixel, or SF/4 to the final output; while the
eight edge-adjacent neighbors contribute SF to each of two smoothed
pixels, or SF/2 overall. In order to use integer arithmetic, these
factors are scaled by 2^16 := 65536.
Also recall that SF := smoothing_factor / 1024. }
memberscale := 16384 - cinfo^.smoothing_factor * 80; { scaled (1-5*SF)/4 }
neighscale := cinfo^.smoothing_factor * 16; { scaled SF/4 }
inrow := 0;
for outrow := 0 to pred(compptr^.v_samp_factor) do
begin
outptr := JSAMPLE_PTR(output_data^[outrow]);
inptr0 := JSAMPLE_PTR(input_data^[inrow]);
inptr1 := JSAMPLE_PTR(input_data^[inrow+1]);
above_ptr := JSAMPLE_PTR(input_data^[inrow-1]);
below_ptr := JSAMPLE_PTR(input_data^[inrow+2]);
{ Special case for first column: pretend column -1 is same as column 0 }
membersum := GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) +
GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]);
neighsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(JSAMPROW(above_ptr)^[1]) +
GETJSAMPLE(below_ptr^) + GETJSAMPLE(JSAMPROW(below_ptr)^[1]) +
GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[2]) +
GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[2]);
Inc(neighsum, neighsum);
Inc(neighsum, GETJSAMPLE(above_ptr^) +
GETJSAMPLE(JSAMPROW(above_ptr)^[2]) +
GETJSAMPLE(below_ptr^) +
GETJSAMPLE(JSAMPROW(below_ptr)^[2]) );
membersum := membersum * memberscale + neighsum * neighscale;
outptr^ := JSAMPLE ((membersum + 32768) shr 16);
Inc(outptr);
prev_inptr0 := inptr0;
prev_inptr1 := inptr1;
Inc(prev_inptr0);
Inc(prev_inptr1);
Inc(inptr0, 2);
Inc(inptr1, 2);
prev_above_ptr := above_ptr;
prev_below_ptr := below_ptr;
Inc(above_ptr, 2);
Inc(below_ptr, 2);
Inc(prev_above_ptr, 1);
Inc(prev_below_ptr, 1);
for colctr := pred(output_cols - 2) downto 0 do
begin
{ sum of pixels directly mapped to this output element }
membersum := GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) +
GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]);
{ sum of edge-neighbor pixels }
neighsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(JSAMPROW(above_ptr)^[1]) +
GETJSAMPLE(below_ptr^) + GETJSAMPLE(JSAMPROW(below_ptr)^[1]) +
GETJSAMPLE(prev_inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[2]) +
GETJSAMPLE(prev_inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[2]);
{ The edge-neighbors count twice as much as corner-neighbors }
Inc(neighsum, neighsum);
{ Add in the corner-neighbors }
Inc(neighsum, GETJSAMPLE(prev_above_ptr^) +
GETJSAMPLE(JSAMPROW(above_ptr)^[2]) +
GETJSAMPLE(prev_below_ptr^) +
GETJSAMPLE(JSAMPROW(below_ptr)^[2]) );
{ form final output scaled up by 2^16 }
membersum := membersum * memberscale + neighsum * neighscale;
{ round, descale and output it }
outptr^ := JSAMPLE ((membersum + 32768) shr 16);
Inc(outptr);
Inc(inptr0, 2);
Inc(inptr1, 2);
Inc(prev_inptr0, 2);
Inc(prev_inptr1, 2);
Inc(above_ptr, 2);
Inc(below_ptr, 2);
Inc(prev_above_ptr, 2);
Inc(prev_below_ptr, 2);
end;
{ Special case for last column }
membersum := GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) +
GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]);
neighsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(JSAMPROW(above_ptr)^[1]) +
GETJSAMPLE(below_ptr^) + GETJSAMPLE(JSAMPROW(below_ptr)^[1]) +
GETJSAMPLE(prev_inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) +
GETJSAMPLE(prev_inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]);
Inc(neighsum, neighsum);
Inc(neighsum, GETJSAMPLE(prev_above_ptr^) +
GETJSAMPLE(JSAMPROW(above_ptr)^[1]) +
GETJSAMPLE(prev_below_ptr^) +
GETJSAMPLE(JSAMPROW(below_ptr)^[1]) );
membersum := membersum * memberscale + neighsum * neighscale;
outptr^ := JSAMPLE ((membersum + 32768) shr 16);
Inc(inrow, 2);
end;
end;
{ Downsample pixel values of a single component.
This version handles the special case of a full-size component,
with smoothing. One row of context is required. }
{METHODDEF}
procedure fullsize_smooth_downsample (cinfo : j_compress_ptr;
compptr : jpeg_component_info_ptr;
input_data : JSAMPARRAY;
output_data : JSAMPARRAY); far;
var
outrow : int;
colctr : JDIMENSION;
output_cols : JDIMENSION;
{register} inptr, above_ptr, below_ptr, outptr : JSAMPLE_PTR;
membersum, neighsum, memberscale, neighscale : INT32;
colsum, lastcolsum, nextcolsum : int;
var
prev_input_data : JSAMPARRAY;
begin
output_cols := compptr^.width_in_blocks * DCTSIZE;
{ Expand input data enough to let all the output samples be generated
by the standard loop. Special-casing padded output would be more
efficient. }
prev_input_data := input_data;
Dec(JSAMPROW_PTR(prev_input_data));
expand_right_edge(prev_input_data, cinfo^.max_v_samp_factor + 2,
cinfo^.image_width, output_cols);
{ Each of the eight neighbor pixels contributes a fraction SF to the
smoothed pixel, while the main pixel contributes (1-8*SF). In order
to use integer arithmetic, these factors are multiplied by 2^16 := 65536.
Also recall that SF := smoothing_factor / 1024. }
memberscale := long(65536) - cinfo^.smoothing_factor * long(512); { scaled 1-8*SF }
neighscale := cinfo^.smoothing_factor * 64; { scaled SF }
for outrow := 0 to pred(compptr^.v_samp_factor) do
begin
outptr := JSAMPLE_PTR(output_data^[outrow]);
inptr := JSAMPLE_PTR(input_data^[outrow]);
above_ptr := JSAMPLE_PTR(input_data^[outrow-1]);
below_ptr := JSAMPLE_PTR(input_data^[outrow+1]);
{ Special case for first column }
colsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(below_ptr^) +
GETJSAMPLE(inptr^);
Inc(above_ptr);
Inc(below_ptr);
membersum := GETJSAMPLE(inptr^);
Inc(inptr);
nextcolsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(below_ptr^) +
GETJSAMPLE(inptr^);
neighsum := colsum + (colsum - membersum) + nextcolsum;
membersum := membersum * memberscale + neighsum * neighscale;
outptr^ := JSAMPLE ((membersum + 32768) shr 16);
Inc(outptr);
lastcolsum := colsum; colsum := nextcolsum;
for colctr := pred(output_cols - 2) downto 0 do
begin
membersum := GETJSAMPLE(inptr^);
Inc(inptr);
Inc(above_ptr);
Inc(below_ptr);
nextcolsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(below_ptr^) +
GETJSAMPLE(inptr^);
neighsum := lastcolsum + (colsum - membersum) + nextcolsum;
membersum := membersum * memberscale + neighsum * neighscale;
outptr^ := JSAMPLE ((membersum + 32768) shr 16);
Inc(outptr);
lastcolsum := colsum; colsum := nextcolsum;
end;
{ Special case for last column }
membersum := GETJSAMPLE(inptr^);
neighsum := lastcolsum + (colsum - membersum) + colsum;
membersum := membersum * memberscale + neighsum * neighscale;
outptr^ := JSAMPLE ((membersum + 32768) shr 16);
end;
end;
{$endif} { INPUT_SMOOTHING_SUPPORTED }
{ Module initialization routine for downsampling.
Note that we must select a routine for each component. }
{GLOBAL}
procedure jinit_downsampler (cinfo : j_compress_ptr);
var
downsample : my_downsample_ptr;
ci : int;
compptr : jpeg_component_info_ptr;
smoothok : boolean;
begin
smoothok := TRUE;
downsample := my_downsample_ptr(
cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
SIZEOF(my_downsampler)) );
cinfo^.downsample := jpeg_downsampler_ptr (downsample);
downsample^.pub.start_pass := start_pass_downsample;
downsample^.pub.downsample := sep_downsample;
downsample^.pub.need_context_rows := FALSE;
if (cinfo^.CCIR601_sampling) then
ERREXIT(j_common_ptr(cinfo), JERR_CCIR601_NOTIMPL);
{ Verify we can handle the sampling factors, and set up method pointers }
compptr := jpeg_component_info_ptr(cinfo^.comp_info);
for ci := 0 to pred(cinfo^.num_components) do
begin
if (compptr^.h_samp_factor = cinfo^.max_h_samp_factor) and
(compptr^.v_samp_factor = cinfo^.max_v_samp_factor) then
begin
{$ifdef INPUT_SMOOTHING_SUPPORTED}
if (cinfo^.smoothing_factor <> 0) then
begin
downsample^.methods[ci] := fullsize_smooth_downsample;
downsample^.pub.need_context_rows := TRUE;
end
else
{$endif}
downsample^.methods[ci] := fullsize_downsample;
end
else
if (compptr^.h_samp_factor * 2 = cinfo^.max_h_samp_factor) and
(compptr^.v_samp_factor = cinfo^.max_v_samp_factor) then
begin
smoothok := FALSE;
downsample^.methods[ci] := h2v1_downsample;
end
else
if (compptr^.h_samp_factor * 2 = cinfo^.max_h_samp_factor) and
(compptr^.v_samp_factor * 2 = cinfo^.max_v_samp_factor) then
begin
{$ifdef INPUT_SMOOTHING_SUPPORTED}
if (cinfo^.smoothing_factor <> 0) then
begin
downsample^.methods[ci] := h2v2_smooth_downsample;
downsample^.pub.need_context_rows := TRUE;
end
else
{$endif}
downsample^.methods[ci] := h2v2_downsample;
end
else
if ((cinfo^.max_h_samp_factor mod compptr^.h_samp_factor) = 0) and
((cinfo^.max_v_samp_factor mod compptr^.v_samp_factor) = 0) then
begin
smoothok := FALSE;
downsample^.methods[ci] := int_downsample;
end
else
ERREXIT(j_common_ptr(cinfo), JERR_FRACT_SAMPLE_NOTIMPL);
Inc(compptr);
end;
{$ifdef INPUT_SMOOTHING_SUPPORTED}
if (cinfo^.smoothing_factor <> 0) and (not smoothok) then
TRACEMS(j_common_ptr(cinfo), 0, JTRC_SMOOTH_NOTIMPL);
{$endif}
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -