📄 transupp.pas
字号:
end; { do_flip_v }
{$ifdef CROP_SUPPORTED}
{LOCAL}
procedure do_transform (srcinfo : j_decompress_ptr;
dstinfo : j_compress_ptr;
src_coef_arrays : jvirt_barray_tbl_ptr;
dst_coef_arrays : jvirt_barray_tbl_ptr;
xoffs : JDIMENSION;
yoffs : JDIMENSION);
{ transform src_coef_arrays so that the xoffs,yoffs (rounded to an even
dct block) are the new origin of the image. copy rather than move because
I'd never finish if I tried to understand the byzantine memory management.
}
var
ci : int;
compptr : jpeg_component_info_ptr;
src_buffer, dst_buffer : JBLOCKARRAY;
dst_blk_x, dst_blk_y : JDIMENSION;
begin
xoffs := xoffs div dstinfo^.max_h_samp_factor * DCTSIZE;
yoffs := yoffs div dstinfo^.max_v_samp_factor * DCTSIZE;
for ci := 0 to dstinfo^.num_components-1 do
begin
compptr := jpeg_component_info_ptr(dstinfo^.comp_info);
Inc(compptr, ci);
dst_blk_y := 0;
while (dst_blk_y < compptr^.height_in_blocks) do
begin
dst_buffer := srcinfo^.mem^.access_virt_barray
(j_common_ptr(srcinfo), dst_coef_arrays^[ci], dst_blk_y, 1, TRUE);
src_buffer := srcinfo^.mem^.access_virt_barray
(j_common_ptr(srcinfo), src_coef_arrays^[ci],
dst_blk_y + yoffs * JDIMENSION(compptr^.v_samp_factor), 1, FALSE);
jcopy_block_row(JBLOCKROW(@src_buffer^[0]^[xoffs * compptr^.h_samp_factor]),
dst_buffer^[0], compptr^.width_in_blocks);
Inc(dst_blk_y);
end;
end;
end; { do_transform }
{$endif}
{LOCAL}
procedure do_transpose (srcinfo : j_decompress_ptr;
dstinfo : j_compress_ptr;
src_coef_arrays : jvirt_barray_tbl_ptr;
dst_coef_arrays : jvirt_barray_tbl_ptr);
{ Transpose source into destination }
var
dst_blk_x, dst_blk_y : JDIMENSION;
ci, i, j, offset_x, offset_y : int;
src_buffer, dst_buffer : JBLOCKARRAY;
src_ptr, dst_ptr : JCOEFPTR;
compptr : jpeg_component_info_ptr;
begin
{ Transposing pixels within a block just requires transposing the
DCT coefficients.
Partial iMCUs at the edges require no special treatment; we simply
process all the available DCT blocks for every component. }
for ci := 0 to dstinfo^.num_components-1 do
begin
compptr := jpeg_component_info_ptr(dstinfo^.comp_info);
Inc(compptr, ci);
dst_blk_y := 0;
while (dst_blk_y < compptr^.height_in_blocks) do
begin
dst_buffer := srcinfo^.mem^.access_virt_barray
(j_common_ptr(srcinfo), dst_coef_arrays^[ci], dst_blk_y,
JDIMENSION (compptr^.v_samp_factor), TRUE);
for offset_y := 0 to compptr^.v_samp_factor-1 do
begin
dst_blk_x := 0;
while (dst_blk_x < compptr^.width_in_blocks) do
begin
src_buffer := srcinfo^.mem^.access_virt_barray
(j_common_ptr(srcinfo), src_coef_arrays^[ci], dst_blk_x,
JDIMENSION (compptr^.h_samp_factor), FALSE);
for offset_x := 0 to compptr^.h_samp_factor-1 do
begin
src_ptr := JCOEFPTR(@(src_buffer^[offset_x]^
[dst_blk_y + offset_y]));
dst_ptr := JCOEFPTR(@(dst_buffer^[offset_y]^
[dst_blk_x + offset_x]));
for i := 0 to DCTSIZE-1 do
for j := 0 to DCTSIZE-1 do
dst_ptr^[j*DCTSIZE+i] := src_ptr^[i*DCTSIZE+j];
end;
Inc(dst_blk_x, compptr^.h_samp_factor);
end;
end;
Inc(dst_blk_y, compptr^.v_samp_factor);
end; { while }
end; { for ci }
end; { do_transpose }
{LOCAL}
procedure do_rot_90 (srcinfo : j_decompress_ptr;
dstinfo : j_compress_ptr;
src_coef_arrays : jvirt_barray_tbl_ptr;
dst_coef_arrays : jvirt_barray_tbl_ptr);
{ 90 degree rotation is equivalent to
1. Transposing the image;
2. Horizontal mirroring.
These two steps are merged into a single processing routine. }
var
MCU_cols, comp_width, dst_blk_x, dst_blk_y : JDIMENSION;
ci, i, j, offset_x, offset_y : int;
src_buffer, dst_buffer : JBLOCKARRAY;
src_ptr, dst_ptr : JCOEFPTR;
compptr : jpeg_component_info_ptr;
begin
{ Because of the horizontal mirror step, we can't process partial iMCUs
at the (output) right edge properly. They just get transposed and
not mirrored. }
MCU_cols := dstinfo^.image_width div (dstinfo^.max_h_samp_factor * DCTSIZE);
for ci := 0 to dstinfo^.num_components-1 do
begin
compptr := jpeg_component_info_ptr(dstinfo^.comp_info);
Inc(compptr, ci);
comp_width := MCU_cols * compptr^.h_samp_factor;
dst_blk_y := 0;
while ( dst_blk_y < compptr^.height_in_blocks) do
begin
dst_buffer := srcinfo^.mem^.access_virt_barray
(j_common_ptr(srcinfo), dst_coef_arrays^[ci], dst_blk_y,
JDIMENSION (compptr^.v_samp_factor), TRUE);
for offset_y := 0 to compptr^.v_samp_factor-1 do
begin
dst_blk_x := 0;
while (dst_blk_x < compptr^.width_in_blocks) do
begin
src_buffer := srcinfo^.mem^.access_virt_barray
(j_common_ptr(srcinfo), src_coef_arrays^[ci], dst_blk_x,
JDIMENSION (compptr^.h_samp_factor), FALSE);
for offset_x := 0 to compptr^.h_samp_factor-1 do
begin
src_ptr := JCOEFPTR(@(src_buffer^[offset_x]^
[dst_blk_y + offset_y]));
if (dst_blk_x < comp_width) then
begin
{ Block is within the mirrorable area. }
dst_ptr := JCOEFPTR(@(dst_buffer^[offset_y]^
[comp_width - dst_blk_x - offset_x - 1]));
i := 0;
while (i < DCTSIZE) do
begin
for j := 0 to DCTSIZE-1 do
dst_ptr^[j*DCTSIZE+i] := src_ptr^[i*DCTSIZE+j];
Inc(i);
for j := 0 to DCTSIZE-1 do
dst_ptr^[j*DCTSIZE+i] := -src_ptr^[i*DCTSIZE+j];
Inc(i);
end;
end
else
begin
{ Edge blocks are transposed but not mirrored. }
dst_ptr := JCOEFPTR(@(dst_buffer^[offset_y]^
[dst_blk_x + offset_x]));
for i := 0 to DCTSIZE-1 do
for j := 0 to DCTSIZE-1 do
dst_ptr^[j*DCTSIZE+i] := src_ptr^[i*DCTSIZE+j];
end;
end;
Inc(dst_blk_x, compptr^.h_samp_factor);
end;
end;
Inc(dst_blk_y, compptr^.v_samp_factor);
end; { while }
end; { for ci }
end; { do_rot_90 }
{LOCAL}
procedure do_rot_270 (srcinfo : j_decompress_ptr;
dstinfo : j_compress_ptr;
src_coef_arrays : jvirt_barray_tbl_ptr;
dst_coef_arrays : jvirt_barray_tbl_ptr);
{ 270 degree rotation is equivalent to
1. Horizontal mirroring;
2. Transposing the image.
These two steps are merged into a single processing routine. }
var
MCU_rows, comp_height, dst_blk_x, dst_blk_y : JDIMENSION;
ci, i, j, offset_x, offset_y : int;
src_buffer, dst_buffer : JBLOCKARRAY;
src_ptr, dst_ptr : JCOEFPTR;
compptr : jpeg_component_info_ptr;
begin
{ Because of the horizontal mirror step, we can't process partial iMCUs
at the (output) bottom edge properly. They just get transposed and
not mirrored. }
MCU_rows := dstinfo^.image_height div (dstinfo^.max_v_samp_factor * DCTSIZE);
for ci := 0 to dstinfo^.num_components-1 do
begin
compptr := jpeg_component_info_ptr(dstinfo^.comp_info);
Inc(compptr, ci);
comp_height := MCU_rows * compptr^.v_samp_factor;
dst_blk_y := 0;
while (dst_blk_y < compptr^.height_in_blocks) do
begin
dst_buffer := srcinfo^.mem^.access_virt_barray
(j_common_ptr(srcinfo), dst_coef_arrays^[ci], dst_blk_y,
JDIMENSION (compptr^.v_samp_factor), TRUE);
for offset_y := 0 to compptr^.v_samp_factor-1 do
begin
dst_blk_x := 0;
while (dst_blk_x < compptr^.width_in_blocks) do
begin
src_buffer := srcinfo^.mem^.access_virt_barray
(j_common_ptr(srcinfo), src_coef_arrays^[ci], dst_blk_x,
JDIMENSION (compptr^.h_samp_factor), FALSE);
for offset_x := 0 to compptr^.h_samp_factor-1 do
begin
dst_ptr := JCOEFPTR(@(dst_buffer^[offset_y]^
[dst_blk_x + offset_x]));
if (dst_blk_y < comp_height) then
begin
{ Block is within the mirrorable area. }
src_ptr := JCOEFPTR(@(src_buffer^[offset_x]^
[comp_height - dst_blk_y - offset_y - 1]));
for i := 0 to DCTSIZE-1 do
begin
j := 0;
while (j < DCTSIZE) do
begin
dst_ptr^[j*DCTSIZE+i] := src_ptr^[i*DCTSIZE+j];
Inc(j);
dst_ptr^[j*DCTSIZE+i] := -src_ptr^[i*DCTSIZE+j];
Inc(j);
end;
end;
end
else
begin
{ Edge blocks are transposed but not mirrored. }
src_ptr := JCOEFPTR(@(src_buffer^[offset_x]^
[dst_blk_y + offset_y]));
for i := 0 to DCTSIZE-1 do
for j := 0 to DCTSIZE-1 do
dst_ptr^[j*DCTSIZE+i] := src_ptr^[i*DCTSIZE+j];
end;
end;
Inc(dst_blk_x, compptr^.h_samp_factor);
end;
end;
Inc(dst_blk_y, compptr^.v_samp_factor);
end; { while }
end; { for ci }
end; { do_rot_270 }
{LOCAL}
procedure do_rot_180 (srcinfo : j_decompress_ptr;
dstinfo : j_compress_ptr;
src_coef_arrays : jvirt_barray_tbl_ptr;
dst_coef_arrays : jvirt_barray_tbl_ptr);
{ 180 degree rotation is equivalent to
1. Vertical mirroring;
2. Horizontal mirroring.
These two steps are merged into a single processing routine. }
var
MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y : JDIMENSION;
ci, i, j, offset_y : int;
src_buffer, dst_buffer : JBLOCKARRAY;
src_row_ptr, dst_row_ptr : JBLOCKROW;
src_ptr, dst_ptr : JCOEF_PTR;
compptr : jpeg_component_info_ptr;
begin
MCU_cols := dstinfo^.image_width div (dstinfo^.max_h_samp_factor * DCTSIZE);
MCU_rows := dstinfo^.image_height div (dstinfo^.max_v_samp_factor * DCTSIZE);
for ci := 0 to dstinfo^.num_components-1 do
begin
compptr := jpeg_component_info_ptr(dstinfo^.comp_info);
Inc(compptr, ci);
comp_width := MCU_cols * compptr^.h_samp_factor;
comp_height := MCU_rows * compptr^.v_samp_factor;
dst_blk_y := 0;
while (dst_blk_y < compptr^.height_in_blocks) do
begin
dst_buffer := srcinfo^.mem^.access_virt_barray
(j_common_ptr(srcinfo), dst_coef_arrays^[ci], dst_blk_y,
JDIMENSION (compptr^.v_samp_factor), TRUE);
if (dst_blk_y < comp_height) then
begin
{ Row is within the vertically mirrorable area. }
src_buffer := srcinfo^.mem^.access_virt_barray
(j_common_ptr(srcinfo), src_coef_arrays^[ci],
comp_height - dst_blk_y - JDIMENSION (compptr^.v_samp_factor),
JDIMENSION (compptr^.v_samp_factor), FALSE);
end
else
begin
{ Bottom-edge rows are only mirrored horizontally. }
src_buffer := srcinfo^.mem^.access_virt_barray
(j_common_ptr(srcinfo), src_coef_arrays^[ci], dst_blk_y,
JDIMENSION (compptr^.v_samp_factor), FALSE);
end;
for offset_y := 0 to compptr^.v_samp_factor-1 do
begin
if (dst_blk_y < comp_height) then
begin
{ Row is within the mirrorable area. }
dst_row_ptr := dst_buffer^[offset_y];
src_row_ptr := src_buffer^[compptr^.v_samp_factor - offset_y - 1];
{ Process the blocks that can be mirrored both ways. }
for dst_blk_x := 0 to comp_width-1 do
begin
dst_ptr := JCOEF_PTR(@(dst_row_ptr^[dst_blk_x]));
src_ptr := JCOEF_PTR(@(src_row_ptr^[comp_width - dst_blk_x - 1]));
i := 0;
while (i < DCTSIZE) do
begin
{ For even row, negate every odd column. }
j := 0;
while (j < DCTSIZE) do
begin
dst_ptr^ := src_ptr^;
Inc(dst_ptr);
Inc(src_ptr);
dst_ptr^ := - src_ptr^;
Inc(dst_ptr);
Inc(src_ptr);
Inc(j, 2);
end;
{ For odd row, negate every even column. }
j := 0;
while (j < DCTSIZE) do
begin
dst_ptr^ := - src_ptr^;
Inc(dst_ptr);
Inc(src_ptr);
dst_ptr^ := src_ptr^;
Inc(dst_ptr);
Inc(src_ptr);
Inc(j, 2);
end;
Inc(i, 2);
end; { while i }
end;
{ Any remaining right-edge blocks are only mirrored vertically. }
for dst_blk_x := comp_width to compptr^.width_in_blocks-1 do
begin
dst_ptr := JCOEF_PTR(@(dst_row_ptr^[dst_blk_x]));
src_ptr := JCOEF_PTR(@(src_row_ptr^[dst_blk_x]));
i := 0;
while (i < DCTSIZE) do
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -