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

📄 jpegfilt.pas

📁 ·ImageEn 2.3.0 ImageEn一组用于图像处理、查看和分析的Delphi控件。能够保存几种图像格式
💻 PAS
📖 第 1 页 / 共 5 页
字号:

const
  OUTPUT_BUF_SIZE = 65536;

procedure init_destination(cinfo: J_COMPRESS_PTR);
var
  dest: PIEJPEGDESTMGR;
begin
  {$ifdef IEPROFILE} try IEProfileBegin('init_destination'); {$endif}
  dest := PIEJPEGDESTMGR(cinfo^.dest);
  getmem(dest^.buffer, OUTPUT_BUF_SIZE * sizeof(JOCTET));
  dest^.pub.next_output_byte := dest^.buffer;
  dest^.pub.free_in_buffer := OUTPUT_BUF_SIZE;
  {$ifdef IEPROFILE} finally IEProfileEnd; end; {$endif}
end;

function empty_output_buffer(cinfo: J_COMPRESS_PTR): boolean;
var
  dest: PIEJPEGDESTMGR;
begin
  {$ifdef IEPROFILE} try IEProfileBegin('empty_output_buffer'); {$endif}
  dest := PIEJPEGDESTMGR(cinfo^.dest);
  if dest^.fs.write(pbyte(dest^.buffer)^, OUTPUT_BUF_SIZE) <> OUTPUT_BUF_SIZE then
    if assigned(dest^.aborting) then
      dest^.aborting^ := true;
  dest^.pub.next_output_byte := dest^.buffer;
  dest^.pub.free_in_buffer := OUTPUT_BUF_SIZE;
  result := true;
  {$ifdef IEPROFILE} finally IEProfileEnd; end; {$endif}
end;

procedure term_destination(cinfo: J_COMPRESS_PTR);
var
  dest: PIEJPEGDESTMGR;
  datacount: integer;
begin
  {$ifdef IEPROFILE} try IEProfileBegin('term_destination'); {$endif}
  dest := PIEJPEGDESTMGR(cinfo^.dest);
  datacount := OUTPUT_BUF_SIZE - dest^.pub.free_in_buffer;
  if datacount > 0 then
  begin
    if dest^.fs.write(pbyte(dest^.buffer)^, datacount) <> datacount then
      if assigned(dest^.aborting) then
        dest^.aborting^ := true;
  end;
  {$ifdef IEPROFILE} finally IEProfileEnd; end; {$endif}
end;

procedure jpeg_ie_dest(cinfo: J_COMPRESS_PTR; fs: TStream; aborting: pboolean);
var
  dest: PIEJPEGDESTMGR;
begin
  {$ifdef IEPROFILE} try IEProfileBegin('jpeg_ie_dest'); {$endif}
  if cinfo^.dest = nil then
    getmem(cinfo^.dest, sizeof(TIEJPEGDESTMGR));
  dest := PIEJPEGDESTMGR(cinfo^.dest);
  dest^.pub.init_destination := @init_destination;
  dest^.pub.empty_output_buffer := @empty_output_buffer;
  dest^.pub.term_destination := @term_destination;
  dest^.fs := fs;
  dest^.aborting := aborting;
  {$ifdef IEPROFILE} finally IEProfileEnd; end; {$endif}
end;

procedure jpeg_ie_dest_free(cinfo: J_COMPRESS_PTR);
var
  dest: PIEJPEGDESTMGR;
begin
  {$ifdef IEPROFILE} try IEProfileBegin('jpeg_ie_dest_free'); {$endif}
  dest := PIEJPEGDESTMGR(cinfo^.dest);
  freemem(dest^.buffer);
  freemem(cinfo^.dest);
  {$ifdef IEPROFILE} finally IEProfileEnd; end; {$endif}
end;

/////////////////////////////////////////////////////////////////////////////////////
// source manager

const
  INPUT_BUF_SIZE = 65536;

procedure init_source(cinfo: J_DECOMPRESS_PTR);
var
  src: PIEJPEGSOURCEMGR;
begin
  {$ifdef IEPROFILE} try IEProfileBegin('init_source'); {$endif}
  src := PIEJPEGSOURCEMGR(cinfo^.src);
  src^.start_of_file := true;
  {$ifdef IEPROFILE} finally IEProfileEnd; end; {$endif}
end;

function fill_input_buffer(cinfo: J_DECOMPRESS_PTR): longbool;
var
  src: PIEJPEGSOURCEMGR;
  nbytes: integer;
begin
  {$ifdef IEPROFILE} try IEProfileBegin('fill_input_buffer'); {$endif}
  src := PIEJPEGSOURCEMGR(cinfo^.src);
  nbytes := src^.fs.Read(pbyte(src^.buffer)^, INPUT_BUF_SIZE);
  if nbytes <= 0 then
  begin
    if src^.start_of_file then
      if assigned(src^.aborting) then
        src^.aborting^ := true;
    pbytearray(src^.buffer)^[0] := $FF;
    pbytearray(src^.buffer)^[1] := JPEG_EOI;
    nbytes := 2;
  end;
  src^.pub.next_input_byte := src^.buffer;
  src^.pub.bytes_in_buffer := nbytes;
  src^.start_of_file := false;
  result := true;
  {$ifdef IEPROFILE} finally IEProfileEnd; end; {$endif}
end;

procedure skip_input_data(cinfo: J_DECOMPRESS_PTR; num_bytes: integer);
var
  src: PIEJPEGSOURCEMGR;
begin
  {$ifdef IEPROFILE} try IEProfileBegin('skip_input_data'); {$endif}
  src := PIEJPEGSOURCEMGR(cinfo^.src);
  if num_bytes > 0 then
  begin
    while num_bytes > src^.pub.bytes_in_buffer do
    begin
      dec(num_bytes, src^.pub.bytes_in_buffer);
      fill_input_buffer(cinfo);
    end;
    inc(src^.pub.next_input_byte, num_bytes);
    dec(src^.pub.bytes_in_buffer, num_bytes);
  end;
  {$ifdef IEPROFILE} finally IEProfileEnd; end; {$endif}
end;

procedure term_source(cinfo: J_DECOMPRESS_PTR);
begin
end;

procedure jpeg_ie_src(cinfo: J_DECOMPRESS_PTR; fs: TStream; aborting: pboolean);
var
  src: PIEJPEGSOURCEMGR;
begin
  {$ifdef IEPROFILE} try IEProfileBegin('jpeg_ie_src'); {$endif}
  if cinfo^.src = nil then
  begin
    getmem(cinfo^.src, sizeof(TIEJPEGSOURCEMGR));
    src := PIEJPEGSOURCEMGR(cinfo^.src);
    getmem(src^.buffer, INPUT_BUF_SIZE * sizeof(JOCTET));
  end;
  src := PIEJPEGSOURCEMGR(cinfo^.src);
  src^.pub.init_source := init_source;
  src^.pub.fill_input_buffer := fill_input_buffer;
  src^.pub.skip_input_data := skip_input_data;
  src^.pub.resync_to_restart := jpeg_resync_to_restart;
  src^.pub.term_source := term_source;
  src^.fs := fs;
  src^.pub.bytes_in_buffer := 0;
  src^.pub.next_input_byte := nil;
  src^.aborting := aborting;
  {$ifdef IEPROFILE} finally IEProfileEnd; end; {$endif}
end;

procedure jpeg_ie_src_free(cinfo: J_DECOMPRESS_PTR);
var
  src: PIEJPEGSOURCEMGR;
begin
  {$ifdef IEPROFILE} try IEProfileBegin('jpeg_ie_src_free'); {$endif}
  src := PIEJPEGSOURCEMGR(cinfo^.src);
  if src <> nil then
  begin
    freemem(src^.buffer);
    freemem(cinfo^.src);
  end;
  {$ifdef IEPROFILE} finally IEProfileEnd; end; {$endif}
end;

/////////////////////////////////////////////////////////////////////////////////////////
// read stream jpeg
// TableStream contains Q tables. It is nil if all is inside Stream.
// Raw=true doesn't convert to RGB but get the original color format

procedure ReadJPegStream(Stream: TStream; TableStream: TStream; Bitmap: TIEBitmap; var IOParams: TIOParamsVals; var xProgress: TProgressRec; Preview: boolean; Raw: boolean; ReadMetaTags:boolean; invertCMYK:boolean; freeICC:boolean; loadicc:boolean; MaxRows:integer);
var
  cinfo: jpeg_decompress_struct;
  jerr: jpeg_error_mgr;
  DestScanLine: pointer;
  LinesRead: integer;
  buff: pbyte;
  pb:pbyte;
  xrgb: PRGB;
  //yrgb: PRGB;
  xx: integer;
  bo: boolean;
  i, bst, dv: integer;
  markers: jpeg_saved_marker_ptr;
  spos: int64;
  tlr: integer; // total lines read
  mi: integer;
  b1,b2:byte;
  dd: double;
  HasICC:boolean;
  xdpi,ydpi:integer;
  oWidth,oHeight:integer;
begin
  {$ifdef IEPROFILE} try IEProfileBegin('ReadJPegStream'); {$endif}
  if IOParams.JPEG_GetExifThumbnail then
  begin
    // try to load the EXIF thumbnail
    if IOParams.EXIF_Bitmap<>nil then
      IOParams.EXIF_Bitmap.FreeImage(true);
    IOParams.JPEG_GetExifThumbnail:=false;
    oWidth:=IOParams.Width; // save requested width because it is changed by ReadJpegStream
    oHeight:=IOParams.Height;
    ReadJpegStream(Stream,TableStream,Bitmap,IOParams,xProgress,true,Raw,true,invertCMYK,freeICC,false,-1); // 2.2.4rc2
    Stream.Position:=0;
    IOParams.JPEG_GetExifThumbnail:=true;
    if assigned(IOParams.EXIF_Bitmap) and not IOParams.EXIF_Bitmap.IsEmpty then
    begin
      Bitmap.Assign( IOParams.EXIF_Bitmap );
      // thumbnails should be already oriented
      //if IOParams.EXIF_HasEXIFData and IOParams.JPEG_EnableAdjustOrientation then
      //  IEAdjustEXIFOrientation(Bitmap,IOParams.EXIF_Orientation);
      exit;
    end;
    Stream.Position:=0;
    IOParams.Width:=oWidth;
    IOParams.Height:=oHeight;
  end;



  IOParams.JPEG_WarningTot := 0;
  IOParams.JPEG_WarningCode := 0;
  spos := JpegTryStream(Stream);
  if spos = -1 then
  begin
    xProgress.Aborting^ := true;
    exit;
  end;
  Stream.Position := spos;

  // load ICC, if present
  if loadicc then
    IEGetJpegICC(Stream, IOParams);

  HasICC:=assigned(IOParams) and assigned(IOParams.fInputICC) and iegEnableCMS;

  try
    buff := nil;
    jerr := jpeg_std_error;
    jerr.aborting := xProgress.Aborting;
    cinfo.common.err := @jerr;
    jpeg_CreateDecompress(cinfo, JPEG_LIB_VERSION, sizeof(cinfo));
    if xProgress.Aborting^ then
      exit;
    if (TableStream <> nil) and (TableStream <> Stream) then
    begin
      // load tables from TableStream
      jpeg_ie_src(@cinfo, TableStream, xProgress.Aborting);
      jpeg_read_header(cinfo, FALSE);
    end;
    jpeg_ie_src(@cinfo, Stream, xProgress.Aborting);
    if xProgress.Aborting^ then
      exit;
    try
      jpeg_save_markers(cinfo, JPEG_COM, $FFFF);
      for xx := JPEG_APP0 to JPEG_APP15 do
        jpeg_save_markers(cinfo, xx, $FFFF);
      jpeg_read_header(cinfo, TRUE);
    except
      xProgress.Aborting^ := true;
      exit;
    end;
    //
    if xProgress.Aborting^ then
      exit;

    IOParams.BitsPerSample := 8;
    cinfo.out_color_space := cinfo.jpeg_color_space;
    case cinfo.jpeg_color_space of
      JCS_RGB:
        begin
          IOParams.JPEG_ColorSpace := ioJPEG_RGB;
          IOParams.SamplesPerPixel := 3;
        end;
      JCS_GRAYSCALE:
        begin
          IOParams.JPEG_ColorSpace := ioJPEG_GRAYLEV;
          IOParams.SamplesPerPixel := 1;
        end;
      JCS_YCbCr:
        begin
          IOParams.JPEG_ColorSpace := ioJPEG_YCbCr;
          IOParams.SamplesPerPixel := 3;
          cinfo.out_color_space := JCS_RGB;
        end;
      JCS_CMYK:
        begin
          IOParams.JPEG_ColorSpace := ioJPEG_CMYK;
          IOParams.SamplesPerPixel := 4;
        end;
      JCS_YCCK:
        begin
          IOParams.JPEG_ColorSpace := ioJPEG_YCbCrK;
          IOParams.SamplesPerPixel := 4;
          cinfo.out_color_space := JCS_CMYK;
        end;
    end;

    if Raw then
      cinfo.out_color_space := JCS_YCbCr;

    case IOParams.JPEG_DCTMethod of
      ioJPEG_ISLOW: cinfo.dct_method := JDCT_ISLOW;
      ioJPEG_IFAST: cinfo.dct_method := JDCT_IFAST;
      ioJPEG_FLOAT: cinfo.dct_method := JDCT_FLOAT;
    end;
    case cinfo.density_unit of
      0, 1: // unknown or inches
        begin
          IOParams.DpiX := cinfo.X_density;
          IOParams.DpiY := cinfo.Y_density;
        end;
      2: // centimeters
        begin
          IOParams.DpiX := trunc(cinfo.X_density / 2.54);
          IOParams.DpiY := trunc(cinfo.Y_density / 2.54);
        end;
    end;
    if IOParams.ColorMap <> nil then
    begin
      freemem(IOParams.ColorMap);
      IOParams.fColorMap := nil;
      IOParams.fColorMapCount := 0;
    end;

⌨️ 快捷键说明

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