📄 transupp.pas
字号:
end;
{LOCAL}
procedure trim_bottom_edge (dstinfo : j_compress_ptr);
var
ci, max_v_samp_factor : int;
MCU_rows : JDIMENSION;
var
v_samp_factor : int;
begin
{ We have to compute max_v_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_v_samp_factor := 1;
for ci := 0 to dstinfo^.num_components-1 do
begin
v_samp_factor := dstinfo^.comp_info^[ci].v_samp_factor;
{max_v_samp_factor := MAX(max_v_samp_factor, v_samp_factor);}
if v_samp_factor > max_v_samp_factor then
max_v_samp_factor := v_samp_factor;
end;
MCU_rows := dstinfo^.image_height div (max_v_samp_factor * DCTSIZE);
if (MCU_rows > 0) then { can't trim to 0 pixels }
dstinfo^.image_height := MCU_rows * (max_v_samp_factor * DCTSIZE);
end;
{$ifdef CROP_SUPPORTED}
{ For cropping, realize and constrain the target area, and reshape the
dstinfo to hold the resulting image.
Input was supplied as WxH[+-]X[+-]Y offsets. Negative offsets are
relative to the lower righthand corner of the image. The region is
expanded so that all boundaries fall on even MCU blocks by rounding
the offsets *down* (at the do_transform() step) and the size *up*. }
{LOCAL}
procedure set_dest_size(dstinfo : j_compress_ptr;
var info : jpeg_transform_info);
var
ci, max_samp_factor : int;
MCU_size, newsize, offset, factor : JDIMENSION;
var
samp_factor : int;
begin
{ Initially the dstinfo is the same size as the srcinfo.
Use it to constrain the offsets: }
if (info.xoffs < 0) then
Inc(info.xoffs, dstinfo^.image_width);
if (info.yoffs < 0) then
Inc(info.yoffs, dstinfo^.image_height);
if (info.xoffs < 0) or (info.xoffs >= dstinfo^.image_width) or
(info.yoffs < 0) or (info.yoffs >= dstinfo^.image_height) then
begin
{jpegtran_error('-cut offsets fall outside source image');}
ERREXIT(j_common_ptr(dstinfo), JERR_CONVERSION_NOTIMPL);
end;
{ use it to constrain the size: }
if (info.newwidth + info.xoffs > dstinfo^.image_width) then
info.newwidth := dstinfo^.image_width - info.xoffs;
if (info.newheight + info.yoffs > dstinfo^.image_height) then
info.newheight := dstinfo^.image_height - info.yoffs;
{ We have to compute max_v/h_samp_factors ourselves,
because it hasn't been set yet in the destination
(and we don't want to use the source's value). }
max_samp_factor := 1;
for ci := 0 to dstinfo^.num_components-1 do
begin
samp_factor := dstinfo^.comp_info^[ci].v_samp_factor;
{max_samp_factor := MAX(max_samp_factor, samp_factor);}
if (max_samp_factor < samp_factor) then
max_samp_factor := samp_factor;
end;
{ Find original (rounded down) and new (rounded up) heights in full
dct blocks, choose the smaller of the two. }
factor := max_samp_factor * DCTSIZE;
MCU_size := dstinfo^.image_height div factor;
newsize := (info.newheight + (info.yoffs mod factor) + factor - 1) div factor;
{MCU_size := MIN(MCU_size, newsize);}
if (MCU_size > newsize) then
MCU_size := newsize;
if (MCU_size > 0) then { can't trim to 0 pixels }
dstinfo^.image_height := MCU_size * factor
else
begin
{jpegtran_error('degenerate -cut height');}
ERREXIT(j_common_ptr(dstinfo), JERR_CONVERSION_NOTIMPL);
end;
max_samp_factor := 1;
for ci := 0 to dstinfo^.num_components-1 do
begin
samp_factor := dstinfo^.comp_info^[ci].h_samp_factor;
{max_samp_factor := MAX(max_samp_factor, samp_factor);}
if (max_samp_factor < samp_factor) then
max_samp_factor := samp_factor;
end;
{ Find original (rounded down) and new (rounded up) heights in full
dct blocks, choose the smaller of the two. }
factor := max_samp_factor * DCTSIZE;
MCU_size := dstinfo^.image_width div factor;
newsize := (info.newwidth + (info.xoffs mod factor) + factor - 1) div factor;
{MCU_size := MIN(MCU_size, newsize);}
if (MCU_size > newsize) then
MCU_size := newsize;
if (MCU_size > 0) then { can't trim to 0 pixels }
dstinfo^.image_width := MCU_size * factor
else
begin
{jpegtran_error('degenerate -cut width');}
ERREXIT(j_common_ptr(dstinfo), JERR_CONVERSION_NOTIMPL);
end;
end;
{$endif}
{ Adjust output image parameters as needed.
This must be called after jpeg_copy_critical_parameters()
and before jpeg_write_coefficients().
The return value is the set of virtual coefficient arrays to be written
(either the ones allocated by jtransform_request_workspace, or the
original source data arrays). The caller will need to pass this value
to jpeg_write_coefficients(). }
{GLOBAL}
function jtransform_adjust_parameters
(srcinfo : j_decompress_ptr;
dstinfo : j_compress_ptr;
src_coef_arrays : jvirt_barray_tbl_ptr;
var info : jpeg_transform_info) : jvirt_barray_tbl_ptr;
var
sv_quant_tbl_no : int;
begin
{ If force-to-grayscale is requested, adjust destination parameters }
if (info.force_grayscale) then
begin
{ We use jpeg_set_colorspace to make sure subsidiary settings get fixed
properly. Among other things, the target h_samp_factor & v_samp_factor
will get set to 1, which typically won't match the source.
In fact we do this even if the source is already grayscale; that
provides an easy way of coercing a grayscale JPEG with funny sampling
factors to the customary 1,1. (Some decoders fail on other factors.) }
if ((dstinfo^.jpeg_color_space = JCS_YCbCr) and
(dstinfo^.num_components = 3)) or
((dstinfo^.jpeg_color_space = JCS_GRAYSCALE) and
(dstinfo^.num_components = 1)) then
begin
{ We have to preserve the source's quantization table number. }
sv_quant_tbl_no := dstinfo^.comp_info^[0].quant_tbl_no;
jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE);
dstinfo^.comp_info^[0].quant_tbl_no := sv_quant_tbl_no;
end
else
begin
{ Sorry, can't do it }
ERREXIT(j_common_ptr(dstinfo), JERR_CONVERSION_NOTIMPL);
end;
end;
{ Correct the destination's image dimensions etc if necessary }
case (info.transform) of
JXFORM_NONE:;
{ Nothing to do }
{$ifdef CROP_SUPPORTED}
JXFORM_CUT:
set_dest_size(dstinfo, info);
{$endif}
JXFORM_FLIP_H:
if (info.trim) then
trim_right_edge(dstinfo);
JXFORM_FLIP_V:
if (info.trim) then
trim_bottom_edge(dstinfo);
JXFORM_TRANSPOSE:
transpose_critical_parameters(dstinfo);
{ transpose does NOT have to trim anything }
JXFORM_TRANSVERSE:
begin
transpose_critical_parameters(dstinfo);
if (info.trim) then
begin
trim_right_edge(dstinfo);
trim_bottom_edge(dstinfo);
end;
end;
JXFORM_ROT_90:
begin
transpose_critical_parameters(dstinfo);
if (info.trim) then
trim_right_edge(dstinfo);
end;
JXFORM_ROT_180:
if (info.trim) then
begin
trim_right_edge(dstinfo);
trim_bottom_edge(dstinfo);
end;
JXFORM_ROT_270:
begin
transpose_critical_parameters(dstinfo);
if (info.trim) then
trim_bottom_edge(dstinfo);
end;
end;
{ Return the appropriate output data set }
if (info.workspace_coef_arrays <> NIL) then
jtransform_adjust_parameters := info.workspace_coef_arrays
else
jtransform_adjust_parameters := src_coef_arrays;
end;
{ Execute the actual transformation, if any.
This must be called *after* jpeg_write_coefficients, because it depends
on jpeg_write_coefficients to have computed subsidiary values such as
the per-component width and height fields in the destination object.
Note that some transformations will modify the source data arrays! }
{GLOBAL}
procedure jtransform_execute_transformation (
srcinfo : j_decompress_ptr;
dstinfo : j_compress_ptr;
src_coef_arrays : jvirt_barray_tbl_ptr;
var info : jpeg_transform_info);
var
dst_coef_arrays : jvirt_barray_tbl_ptr;
begin
dst_coef_arrays := info.workspace_coef_arrays;
case (info.transform) of
JXFORM_NONE:;
{$ifdef CROP_SUPPORTED}
JXFORM_CUT:
do_transform(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays,
info.xoffs, info.yoffs);
{$endif}
JXFORM_FLIP_H:
do_flip_h(srcinfo, dstinfo, src_coef_arrays);
JXFORM_FLIP_V:
do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
JXFORM_TRANSPOSE:
do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
JXFORM_TRANSVERSE:
do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
JXFORM_ROT_90:
do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
JXFORM_ROT_180:
do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
JXFORM_ROT_270:
do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
end;
end;
{$endif} { TRANSFORMS_SUPPORTED }
{ Setup decompression object to save desired markers in memory.
This must be called before jpeg_read_header() to have the desired effect. }
{GLOBAL}
procedure jcopy_markers_setup (srcinfo : j_decompress_ptr;
option : JCOPY_OPTION);
var
m : int;
begin
{$ifdef SAVE_MARKERS_SUPPORTED}
{ Save comments except under NONE option }
if (option <> JCOPYOPT_NONE) then
begin
jpeg_save_markers(srcinfo, JPEG_COM, $FFFF);
end;
{ Save all types of APPn markers iff ALL option }
if (option = JCOPYOPT_ALL) then
begin
for m := 0 to 16-1 do
jpeg_save_markers(srcinfo, JPEG_APP0 + m, $FFFF);
end;
{$endif} { SAVE_MARKERS_SUPPORTED }
end;
{ Copy markers saved in the given source object to the destination object.
This should be called just after jpeg_start_compress() or
jpeg_write_coefficients().
Note that those routines will have written the SOI, and also the
JFIF APP0 or Adobe APP14 markers if selected. }
{GLOBAL}
procedure jcopy_markers_execute (srcinfo : j_decompress_ptr;
dstinfo : j_compress_ptr;
option : JCOPY_OPTION);
var
marker : jpeg_saved_marker_ptr;
{$ifdef NEED_FAR_POINTERS}
var
i : uint;
{$endif}
begin
{ In the current implementation, we don't actually need to examine the
option flag here; we just copy everything that got saved.
But to avoid confusion, we do not output JFIF and Adobe APP14 markers
if the encoder library already wrote one. }
marker := srcinfo^.marker_list;
while (marker <> NIL) do
begin
if (dstinfo^.write_JFIF_header) and
(marker^.marker = JPEG_APP0) and
(marker^.data_length >= 5) and
( GETJOCTET(marker^.data^[0]) = $4A ) and
( GETJOCTET(marker^.data^[1]) = $46 ) and
( GETJOCTET(marker^.data^[2]) = $49 ) and
( GETJOCTET(marker^.data^[3]) = $46 ) and
( GETJOCTET(marker^.data^[4]) = 0 ) then
begin
marker := marker^.next;
continue; { reject duplicate JFIF }
end;
if (dstinfo^.write_Adobe_marker ) and
( marker^.marker = JPEG_APP0+14 ) and
( marker^.data_length >= 5 ) and
( GETJOCTET(marker^.data^[0]) = $41 ) and
( GETJOCTET(marker^.data^[1]) = $64 ) and
( GETJOCTET(marker^.data^[2]) = $6F ) and
( GETJOCTET(marker^.data^[3]) = $62 ) and
( GETJOCTET(marker^.data^[4]) = $65 ) then
begin
marker := marker^.next;
continue; { reject duplicate Adobe }
end;
{$ifdef NEED_FAR_POINTERS}
{ We could use jpeg_write_marker if the data weren't FAR... }
begin
jpeg_write_m_header(dstinfo, marker^.marker, marker^.data_length);
for i := 0 to marker^.data_length-1 do
jpeg_write_m_byte(dstinfo, marker^.data^[i]);
end;
{$else}
jpeg_write_marker(dstinfo, marker^.marker,
JOCTETPTR(marker^.data), marker^.data_length);
{$endif}
marker := marker^.next;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -