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

📄 jdmarker.pas

📁 DELPHI版的JPEG文件解码源程序
💻 PAS
📖 第 1 页 / 共 5 页
字号:
          { Reload the local copies }
          next_input_byte := datasrc^.next_input_byte;
          bytes_in_buffer := datasrc^.bytes_in_buffer;
        end;
        Dec( bytes_in_buffer );

        tmp := (uint( GETJOCTET(next_input_byte^)) shl 8);
        Inc( next_input_byte );
        { make a byte available.
          Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
          but we must reload the local copies after a successful fill. }
          if (bytes_in_buffer = 0) then
          begin
            if (not datasrc^.fill_input_buffer(cinfo)) then
            begin
              get_dqt := FALSE;
              exit;
            end;
            { Reload the local copies }
            next_input_byte := datasrc^.next_input_byte;
            bytes_in_buffer := datasrc^.bytes_in_buffer;
          end;
          Dec( bytes_in_buffer );

        Inc( tmp, GETJOCTET( next_input_byte^));
        Inc( next_input_byte );

      end
      else
      begin
      { Read a byte into variable tmp. If must suspend, return FALSE. }
      { make a byte available.
        Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
        but we must reload the local copies after a successful fill. }
        if (bytes_in_buffer = 0) then
        begin
          if (not datasrc^.fill_input_buffer(cinfo)) then
          begin
            get_dqt := FALSE;
            exit;
          end;
          { Reload the local copies }
          next_input_byte := datasrc^.next_input_byte;
          bytes_in_buffer := datasrc^.bytes_in_buffer;
        end;
        Dec( bytes_in_buffer );

        tmp := GETJOCTET(next_input_byte^);
        Inc(next_input_byte);
      end;

      { We convert the zigzag-order table to natural array order. }
      quant_ptr^.quantval[jpeg_natural_order[i]] := UINT16(tmp);
    end;

    if (cinfo^.err^.trace_level >= 2) then
    begin
      i := 0;
      while i < Pred(DCTSIZE2) do
      begin
        {$IFDEF DEBUG}
	TRACEMS8(j_common_ptr(cinfo), 2, JTRC_QUANTVALS,
		 quant_ptr^.quantval[i],   quant_ptr^.quantval[i+1],
		 quant_ptr^.quantval[i+2], quant_ptr^.quantval[i+3],
		 quant_ptr^.quantval[i+4], quant_ptr^.quantval[i+5],
		 quant_ptr^.quantval[i+6], quant_ptr^.quantval[i+7]);
        {$ENDIF}
        Inc(i, 8);
      end;
    end;

    Dec( length, DCTSIZE2+1 );
    if (prec <> 0) then
      Dec( length, DCTSIZE2 );
  end;

  if (length <> 0) then
    ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH);

  { Unload the local copies --- do this only at a restart boundary }
  datasrc^.next_input_byte := next_input_byte;
  datasrc^.bytes_in_buffer := bytes_in_buffer;

  get_dqt := TRUE;
end;  { get_dqt }


{LOCAL}
function get_dri (cinfo : j_decompress_ptr) : boolean;
{ Process a DRI marker }
var
  length : INT32;
  tmp : uint;
var
  datasrc : jpeg_source_mgr_ptr;
  next_input_byte : JOCTETptr;
  bytes_in_buffer : size_t;
begin
  datasrc := cinfo^.src;
  next_input_byte := datasrc^.next_input_byte;
  bytes_in_buffer := datasrc^.bytes_in_buffer;

{ Read two bytes interpreted as an unsigned 16-bit integer.
  length should be declared unsigned int or perhaps INT32. }

{ make a byte available.
  Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
  but we must reload the local copies after a successful fill. }
  if (bytes_in_buffer = 0) then
  begin
    if (not datasrc^.fill_input_buffer(cinfo)) then
    begin
      get_dri := FALSE;
      exit;
    end;
    { Reload the local copies }
    next_input_byte := datasrc^.next_input_byte;
    bytes_in_buffer := datasrc^.bytes_in_buffer;
  end;
  Dec( bytes_in_buffer );

  length := (uint( GETJOCTET(next_input_byte^)) shl 8);
  Inc( next_input_byte );
  { make a byte available.
    Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
    but we must reload the local copies after a successful fill. }
    if (bytes_in_buffer = 0) then
    begin
      if (not datasrc^.fill_input_buffer(cinfo)) then
      begin
        get_dri := FALSE;
        exit;
      end;
      { Reload the local copies }
      next_input_byte := datasrc^.next_input_byte;
      bytes_in_buffer := datasrc^.bytes_in_buffer;
    end;
    Dec( bytes_in_buffer );

  Inc( length, GETJOCTET( next_input_byte^));
  Inc( next_input_byte );

  if (length <> 4) then
    ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH);

{ Read two bytes interpreted as an unsigned 16-bit integer.
  tmp should be declared unsigned int or perhaps INT32. }

{ make a byte available.
  Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
  but we must reload the local copies after a successful fill. }
  if (bytes_in_buffer = 0) then
  begin
    if (not datasrc^.fill_input_buffer(cinfo)) then
    begin
      get_dri := FALSE;
      exit;
    end;
    { Reload the local copies }
    next_input_byte := datasrc^.next_input_byte;
    bytes_in_buffer := datasrc^.bytes_in_buffer;
  end;
  Dec( bytes_in_buffer );

  tmp := (uint( GETJOCTET(next_input_byte^)) shl 8);
  Inc( next_input_byte );
  { make a byte available.
    Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
    but we must reload the local copies after a successful fill. }
    if (bytes_in_buffer = 0) then
    begin
      if (not datasrc^.fill_input_buffer(cinfo)) then
      begin
        get_dri := FALSE;
        exit;
      end;
      { Reload the local copies }
      next_input_byte := datasrc^.next_input_byte;
      bytes_in_buffer := datasrc^.bytes_in_buffer;
    end;
    Dec( bytes_in_buffer );

  Inc( tmp, GETJOCTET( next_input_byte^));
  Inc( next_input_byte );

  {$IFDEF DEBUG}
  TRACEMS1(j_common_ptr(cinfo), 1, JTRC_DRI, tmp);
  {$ENDIF}

  cinfo^.restart_interval := tmp;

  { Unload the local copies --- do this only at a restart boundary }
  datasrc^.next_input_byte := next_input_byte;
  datasrc^.bytes_in_buffer := bytes_in_buffer;

  get_dri := TRUE;
end;  { get_dri }


{ Routines for processing APPn and COM markers.
  These are either saved in memory or discarded, per application request.
  APP0 and APP14 are specially checked to see if they are
  JFIF and Adobe markers, respectively. }

const
  APP0_DATA_LEN	= 14;   { Length of interesting data in APP0 }
  APP14_DATA_LEN = 12;  { Length of interesting data in APP14 }
  APPN_DATA_LEN = 14;   { Must be the largest of the above!! }


{LOCAL}
procedure examine_app0 (cinfo : j_decompress_ptr;
                        var data : array of JOCTET;
                        datalen : uint;
                        remaining : INT32);

{ Examine first few bytes from an APP0.
  Take appropriate action if it is a JFIF marker.
  datalen is # of bytes at data[], remaining is length of rest of marker data.
}
{$IFDEF DEBUG}
var
  totallen : INT32;
{$ENDIF}  
begin
  {$IFDEF DEBUG}
  totallen := INT32(datalen) + remaining;
  {$ENDIF}
  if (datalen >= APP0_DATA_LEN) and
     (GETJOCTET(data[0]) = $4A) and
     (GETJOCTET(data[1]) = $46) and
     (GETJOCTET(data[2]) = $49) and
     (GETJOCTET(data[3]) = $46) and
     (GETJOCTET(data[4]) = 0) then
  begin
    { Found JFIF APP0 marker: save info }
    cinfo^.saw_JFIF_marker := TRUE;
    cinfo^.JFIF_major_version := GETJOCTET(data[5]);
    cinfo^.JFIF_minor_version := GETJOCTET(data[6]);
    cinfo^.density_unit := GETJOCTET(data[7]);
    cinfo^.X_density := (GETJOCTET(data[8]) shl 8) + GETJOCTET(data[9]);
    cinfo^.Y_density := (GETJOCTET(data[10]) shl 8) + GETJOCTET(data[11]);
    { Check version.
      Major version must be 1, anything else signals an incompatible change.
      (We used to treat this as an error, but now it's a nonfatal warning,
      because some bozo at Hijaak couldn't read the spec.)
      Minor version should be 0..2, but process anyway if newer. }

    if (cinfo^.JFIF_major_version <> 1) then
      WARNMS2(j_common_ptr(cinfo), JWRN_JFIF_MAJOR,
	      cinfo^.JFIF_major_version, cinfo^.JFIF_minor_version);
    { Generate trace messages }
    {$IFDEF DEBUG}
    TRACEMS5(j_common_ptr(cinfo), 1, JTRC_JFIF,
	     cinfo^.JFIF_major_version, cinfo^.JFIF_minor_version,
	     cinfo^.X_density, cinfo^.Y_density, cinfo^.density_unit);
    { Validate thumbnail dimensions and issue appropriate messages }
    if (GETJOCTET(data[12]) or GETJOCTET(data[13])) <> 0 then
      TRACEMS2(j_common_ptr(cinfo), 1, JTRC_JFIF_THUMBNAIL,
	       GETJOCTET(data[12]), GETJOCTET(data[13]));
    Dec(totallen, APP0_DATA_LEN);
    if (totallen <>
	( INT32(GETJOCTET(data[12])) * INT32(GETJOCTET(data[13])) * INT32(3) )) then
      TRACEMS1(j_common_ptr(cinfo), 1, JTRC_JFIF_BADTHUMBNAILSIZE, int(totallen));
    {$ENDIF}
  end
  else
    if (datalen >= 6) and
      (GETJOCTET(data[0]) = $4A) and
      (GETJOCTET(data[1]) = $46) and
      (GETJOCTET(data[2]) = $58) and
      (GETJOCTET(data[3]) = $58) and
      (GETJOCTET(data[4]) = 0) then
    begin
    { Found JFIF "JFXX" extension APP0 marker }
    { The library doesn't actually do anything with these,
      but we try to produce a helpful trace message. }
      {$IFDEF DEBUG}
      case (GETJOCTET(data[5])) of
        $10:
          TRACEMS1(j_common_ptr(cinfo), 1, JTRC_THUMB_JPEG, int(totallen));
        $11:
          TRACEMS1(j_common_ptr(cinfo), 1, JTRC_THUMB_PALETTE, int(totallen));
        $13:
          TRACEMS1(j_common_ptr(cinfo), 1, JTRC_THUMB_RGB, int(totallen));
        else
          TRACEMS2(j_common_ptr(cinfo), 1, JTRC_JFIF_EXTENSION,
	           GETJOCTET(data[5]), int(totallen));
      end;
      {$ENDIF}
    end
    else
    begin
      { Start of APP0 does not match "JFIF" or "JFXX", or too short }
      {$IFDEF DEBUG}
      TRACEMS1(j_common_ptr(cinfo), 1, JTRC_APP0, int(totallen));
      {$ENDIF}
    end;
end;


{LOCAL}
procedure examine_app14 (cinfo : j_decompress_ptr;
                         var data : array of JOCTET;
	                 datalen : uint;
                         remaining : INT32);
{ Examine first few bytes from an APP14.
  Take appropriate action if it is an Adobe marker.
  datalen is # of bytes at data[], remaining is length of rest of marker data.
 }
var
  {$IFDEF DEBUG}
  version, flags0, flags1,
  {$ENDIF}
  transform : uint;
begin
  if (datalen >= APP14_DATA_LEN) and
     (GETJOCTET(data[0]) = $41) and
     (GETJOCTET(data[1]) = $64) and
     (GETJOCTET(data[2]) = $6F) and
     (GETJOCTET(data[3]) = $62) and
     (GETJOCTET(data[4]) = $65) then
  begin
    { Found Adobe APP14 marker }
    {$IFDEF DEBUG}
    version := (GETJOCTET(data[5]) shl 8) + GETJOCTET(data[6]);
    flags0 := (GETJOCTET(data[7]) shl 8) + GETJOCTET(data[8]);
    flags1 := (GETJOCTET(data[9]) shl 8) + GETJOCTET(data[10]);
    {$ENDIF}
    transform := GETJOCTET(data[11]);
    {$IFDEF DEBUG}
    TRACEMS4(j_common_ptr(cinfo), 1, JTRC_ADOBE, version, flags0, flags1, transform);
    {$ENDIF}
    cinfo^.saw_Adobe_marker := TRUE;
    cinfo^.Adobe_transform := UINT8 (transform);
  end
  else
  begin
    { Start of APP14 does not match "Adobe", or too short }
    {$IFDEF DEBUG}
    TRACEMS1(j_common_ptr(cinfo), 1, JTRC_APP14, int (datalen + remaining));
    {$ENDIF}
  end;
end;


{METHODDEF}
function get_interesting_appn (cinfo : j_decompress_ptr) : boolean; far;
{ Process an APP0 or APP14 marker without saving it }
var
  length : INT32;
  b : array[0..APPN_DATA_LEN-1] of JOCTET;
  i, numtoread : uint;
var
  datasrc : jpeg_source_mgr_ptr;
  next_input_byte : JOCTETptr;
  bytes_in_buffer : size_t;
begin
  datasrc := cinfo^.src;
  next_input_byte := datasrc^.next_input_byte;
  bytes_in_buffer := datasrc^.bytes_in_buffer;

{ Read two bytes interpreted as an unsigned 16-bit integer.
  length should be declared unsigned int or perhaps INT32. }

  { make a byte available.
    Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
    but we must reload the local copies after a successful fill. }
  if (bytes_in_buffer = 0) then
  begin
    if (not datasrc^.fill_input_buffer(cinfo)) then
    begin
      get_interesting_appn := FALSE;
      exit;
    end;
    { Reload the local copies }
    next_input_byte := datasrc^.next_input_byte;
    bytes_in_buffer := datasrc^.bytes_in_buffer;
  end;
  Dec( bytes_in_buffer );

  length := (uint( GETJOCTET(next_input_byte^)) shl 8);
  Inc( next_input_byte );

  { make a byte available.
    Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
    but we must reload the local copies after a successful fill. }
  if (bytes_in_buffer = 0) then
  begin
    if (not datasrc^.fill_input_buffer(cinfo)) then
    begin
      get_interesting_appn := FALSE;
      exit;
    end;
    { Reload the local copies }
    next_input_byte := datasrc^.next_input_byte;
    bytes_in_buffer := datasrc^.bytes_in_buffer;
  end;
  Dec( bytes_in_buffer );

  Inc( length, GETJOCTET(next_input_byte^));
  Inc( next_input_byte );

  Dec(length, 2);

  { get the interesting part of the marker data }
  if (length >= APPN_DATA_LEN) then
    numtoread := APPN_DATA_LEN
  else
    if (length > 0) then
      numtoread := uint(length)
    else
      numtoread := 0;
  for i := 0 to numtoread-1 do
  begin
  { Read a byte into b[i]. If must suspend, return FALSE. }
    { make a byte available.
      Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
      but we must reload the local copies after a successful fill. }
    if (bytes_in_buffer = 0) then
    begin
      if (not datasrc^.fill_input_buffer(cinfo)) then
      begin
        get_interesting_appn := FALSE;
        exit;
      end;
      { Reload the local copies }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -