⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 transupp.pas

📁 DELPHI版的JPEG文件解码源程序
💻 PAS
📖 第 1 页 / 共 4 页
字号:
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 + -