📄 transupp.pas
字号:
for j := 0 to DCTSIZE-1 do
begin
dst_ptr^ := src_ptr^;
Inc(dst_ptr);
Inc(src_ptr);
end;
for j := 0 to DCTSIZE-1 do
begin
dst_ptr^ := - src_ptr^;
Inc(dst_ptr);
Inc(src_ptr);
end;
Inc(i, 2);
end
end
end
else
begin
{ Remaining rows are just mirrored horizontally. }
dst_row_ptr := dst_buffer^[offset_y];
src_row_ptr := src_buffer^[offset_y];
{ Process the blocks that can be mirrored. }
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 < DCTSIZE2) do
begin
dst_ptr^ := src_ptr^;
Inc(dst_ptr);
Inc(src_ptr);
dst_ptr^ := - src_ptr^;
Inc(dst_ptr);
Inc(src_ptr);
Inc(i, 2);
end;
end;
{ Any remaining right-edge blocks are only copied. }
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]));
for i := 0 to DCTSIZE2-1 do
begin
dst_ptr^ := src_ptr^;
Inc(dst_ptr);
Inc(src_ptr);
end;
end;
end;
end;
Inc(dst_blk_y, compptr^.v_samp_factor) ;
end; { while }
end; { for ci }
end; { do_rot_180 }
{LOCAL}
procedure do_transverse (srcinfo : j_decompress_ptr;
dstinfo : j_compress_ptr;
src_coef_arrays : jvirt_barray_tbl_ptr;
dst_coef_arrays : jvirt_barray_tbl_ptr);
{ Transverse transpose is equivalent to
1. 180 degree rotation;
2. Transposition;
or
1. Horizontal mirroring;
2. Transposition;
3. Horizontal mirroring.
These 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_x, offset_y : int;
src_buffer, dst_buffer : JBLOCKARRAY;
src_ptr, dst_ptr : JCOEFPTR;
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);
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
if (dst_blk_y < comp_height) then
begin
src_ptr := JCOEFPTR(@(src_buffer^[offset_x]^
[comp_height - dst_blk_y - offset_y - 1]));
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
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;
Inc(i);
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;
Inc(i);
end
end
else
begin
{ Right-edge blocks are mirrored in y only }
dst_ptr := JCOEFPTR(@(dst_buffer^[offset_y]^
[dst_blk_x + offset_x]));
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;
end
else
begin
src_ptr := JCOEFPTR(@(src_buffer^[offset_x]^
[dst_blk_y + offset_y]));
if (dst_blk_x < comp_width) then
begin
{ Bottom-edge blocks are mirrored in x only }
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
{ At lower right corner, just transpose, no mirroring }
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;
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_transverse }
{ Request any required workspace.
We allocate the workspace virtual arrays from the source decompression
object, so that all the arrays (both the original data and the workspace)
will be taken into account while making memory management decisions.
Hence, this routine must be called after jpeg_read_header (which reads
the image dimensions) and before jpeg_read_coefficients (which realizes
the source's virtual arrays). }
{GLOBAL}
procedure jtransform_request_workspace (
srcinfo : j_decompress_ptr;
var info : jpeg_transform_info);
var
coef_arrays : jvirt_barray_tbl_ptr;
compptr : jpeg_component_info_ptr;
ci : int;
begin
coef_arrays := NIL;
if (info.force_grayscale) and (srcinfo^.jpeg_color_space = JCS_YCbCr)
and (srcinfo^.num_components = 3) then
begin
{ We'll only process the first component }
info.num_components := 1;
end
else
begin
{ Process all the components }
info.num_components := srcinfo^.num_components;
end;
case (info.transform) of
JXFORM_NONE,
JXFORM_FLIP_H:;
{ Don't need a workspace array }
{$ifdef CROP_SUPPORTED}
JXFORM_CUT,
{ really cut needs smaller arrays if you want to figure it out }
{$endif}
JXFORM_FLIP_V,
JXFORM_ROT_180:
begin
{ Need workspace arrays having same dimensions as source image.
Note that we allocate arrays padded out to the next iMCU boundary,
so that transform routines need not worry about missing edge blocks. }
coef_arrays := jvirt_barray_tbl_ptr (
srcinfo^.mem^.alloc_small (j_common_ptr(srcinfo), JPOOL_IMAGE,
SIZEOF(jvirt_barray_ptr) * info.num_components) );
for ci := 0 to info.num_components-1 do
begin
compptr := jpeg_component_info_ptr(srcinfo^.comp_info);
Inc(compptr, ci);
coef_arrays^[ci] := srcinfo^.mem^.request_virt_barray
(j_common_ptr(srcinfo), JPOOL_IMAGE, FALSE,
JDIMENSION (jround_up( long (compptr^.width_in_blocks),
long (compptr^.h_samp_factor)) ),
JDIMENSION (jround_up( long (compptr^.height_in_blocks),
long (compptr^.v_samp_factor)) ),
JDIMENSION (compptr^.v_samp_factor));
end;
end;
JXFORM_TRANSPOSE,
JXFORM_TRANSVERSE,
JXFORM_ROT_90,
JXFORM_ROT_270:
begin
{ Need workspace arrays having transposed dimensions.
Note that we allocate arrays padded out to the next iMCU boundary,
so that transform routines need not worry about missing edge blocks. }
coef_arrays := jvirt_barray_tbl_ptr(
srcinfo^.mem^.alloc_small (j_common_ptr(srcinfo), JPOOL_IMAGE,
SIZEOF(jvirt_barray_ptr) * info.num_components) );
for ci := 0 to info.num_components-1 do
begin
compptr := jpeg_component_info_ptr(srcinfo^.comp_info);
Inc(compptr, ci);
coef_arrays^[ci] := srcinfo^.mem^.request_virt_barray
(j_common_ptr(srcinfo), JPOOL_IMAGE, FALSE,
JDIMENSION ( jround_up( long(compptr^.height_in_blocks),
long(compptr^.v_samp_factor) ) ),
JDIMENSION ( jround_up( long(compptr^.width_in_blocks),
long(compptr^.h_samp_factor) ) ),
JDIMENSION ( compptr^.h_samp_factor ) );
end;
end;
end;
info.workspace_coef_arrays := coef_arrays;
end;
{ Transpose destination image parameters }
{LOCAL}
procedure transpose_critical_parameters (dstinfo : j_compress_ptr);
var
tblno, i, j, ci, itemp : int;
compptr : jpeg_component_info_ptr;
qtblptr : JQUANT_TBL_PTR;
dtemp : JDIMENSION;
qtemp : UINT16;
begin
{ Transpose basic image dimensions }
dtemp := dstinfo^.image_width;
dstinfo^.image_width := dstinfo^.image_height;
dstinfo^.image_height := dtemp;
{ Transpose sampling factors }
for ci := 0 to dstinfo^.num_components-1 do
begin
compptr := jpeg_component_info_ptr(dstinfo^.comp_info);
Inc(compptr, ci);
itemp := compptr^.h_samp_factor;
compptr^.h_samp_factor := compptr^.v_samp_factor;
compptr^.v_samp_factor := itemp;
end;
{ Transpose quantization tables }
for tblno := 0 to NUM_QUANT_TBLS-1 do
begin
qtblptr := dstinfo^.quant_tbl_ptrs[tblno];
if (qtblptr <> NIL) then
begin
for i := 0 to DCTSIZE-1 do
begin
for j := 0 to i-1 do
begin
qtemp := qtblptr^.quantval[i*DCTSIZE+j];
qtblptr^.quantval[i*DCTSIZE+j] := qtblptr^.quantval[j*DCTSIZE+i];
qtblptr^.quantval[j*DCTSIZE+i] := qtemp;
end;
end;
end;
end;
end;
{ Trim off any partial iMCUs on the indicated destination edge }
{LOCAL}
procedure trim_right_edge (dstinfo : j_compress_ptr);
var
ci, max_h_samp_factor : int;
MCU_cols : JDIMENSION;
var
h_samp_factor : int;
begin
{ We have to compute max_h_samp_factor ourselves,
because it hasn't been set yet in the destination
(and we don't want to use the source's value). }
max_h_samp_factor := 1;
for ci := 0 to dstinfo^.num_components-1 do
begin
h_samp_factor := dstinfo^.comp_info^[ci].h_samp_factor;
{max_h_samp_factor := MAX(max_h_samp_factor, h_samp_factor);}
if h_samp_factor > max_h_samp_factor then
max_h_samp_factor := h_samp_factor;
end;
MCU_cols := dstinfo^.image_width div (max_h_samp_factor * DCTSIZE);
if (MCU_cols > 0) then { can't trim to 0 pixels }
dstinfo^.image_width := MCU_cols * (max_h_samp_factor * DCTSIZE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -