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

📄 jidctred.pas

📁 用pascal寫的jpeg codec, 測試過的
💻 PAS
📖 第 1 页 / 共 2 页
字号:
Unit JIDctRed;


{ This file contains inverse-DCT routines that produce reduced-size output:
  either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block.

  The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M)
  algorithm used in jidctint.c.  We simply replace each 8-to-8 1-D IDCT step
  with an 8-to-4 step that produces the four averages of two adjacent outputs
  (or an 8-to-2 step producing two averages of four outputs, for 2x2 output).
  These steps were derived by computing the corresponding values at the end
  of the normal LL&M code, then simplifying as much as possible.

  1x1 is trivial: just take the DC coefficient divided by 8.

  See jidctint.c for additional comments. }


{ Original : jidctred.c ; Copyright (C) 1994-1996, Thomas G. Lane. }

interface

{$I jconfig.inc}

uses
  jmorecfg,
  jinclude,
  jpeglib,
  jdct;         	{ Private declarations for DCT subsystem }

{ Perform dequantization and inverse DCT on one block of coefficients,
  producing a reduced-size 1x1 output block. }

{GLOBAL}
procedure jpeg_idct_1x1 (cinfo : j_decompress_ptr;
                         compptr : jpeg_component_info_ptr;
	                 coef_block : JCOEFPTR;
	                 output_buf : JSAMPARRAY;
                         output_col : JDIMENSION);

{ Perform dequantization and inverse DCT on one block of coefficients,
  producing a reduced-size 2x2 output block. }

{GLOBAL}
procedure jpeg_idct_2x2 (cinfo : j_decompress_ptr;
                         compptr : jpeg_component_info_ptr;
	                 coef_block : JCOEFPTR;
                         output_buf : JSAMPARRAY;
                         output_col : JDIMENSION);

{ Perform dequantization and inverse DCT on one block of coefficients,
  producing a reduced-size 4x4 output block. }

{GLOBAL}
procedure jpeg_idct_4x4 (cinfo : j_decompress_ptr;
                         compptr : jpeg_component_info_ptr;
	                 coef_block : JCOEFPTR;
	                 output_buf : JSAMPARRAY;
                         output_col : JDIMENSION);

implementation

{ This module is specialized to the case DCTSIZE = 8. }

{$ifdef DCTSIZE <> 8}
  Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err }
{$endif}


{ Scaling is the same as in jidctint.c. }

{$ifdef BITS_IN_JSAMPLE_IS_8}
const
  CONST_BITS = 13;
  PASS1_BITS = 2;
{$else}
const
  CONST_BITS = 13;
  PASS1_BITS = 1;	{ lose a little precision to avoid overflow }
{$endif}

{ Convert a positive real constant to an integer scaled by CONST_SCALE. }
const
  ONE   = INT32(1);
  CONST_SCALE = (ONE shl CONST_BITS);
const
  FIX_0_211164243 = INT32(Round(CONST_SCALE * 0.211164243)); {1730}
  FIX_0_509795579 = INT32(Round(CONST_SCALE * 0.509795579)); {4176}
  FIX_0_601344887 = INT32(Round(CONST_SCALE * 0.601344887)); {4926}
  FIX_0_720959822 = INT32(Round(CONST_SCALE * 0.720959822)); {5906}
  FIX_0_765366865 = INT32(Round(CONST_SCALE * 0.765366865)); {6270}
  FIX_0_850430095 = INT32(Round(CONST_SCALE * 0.850430095)); {6967}
  FIX_0_899976223 = INT32(Round(CONST_SCALE * 0.899976223)); {7373}
  FIX_1_061594337 = INT32(Round(CONST_SCALE * 1.061594337)); {8697}
  FIX_1_272758580 = INT32(Round(CONST_SCALE * 1.272758580)); {10426}
  FIX_1_451774981 = INT32(Round(CONST_SCALE * 1.451774981)); {11893}
  FIX_1_847759065 = INT32(Round(CONST_SCALE * 1.847759065)); {15137}
  FIX_2_172734803 = INT32(Round(CONST_SCALE * 2.172734803)); {17799}
  FIX_2_562915447 = INT32(Round(CONST_SCALE * 2.562915447)); {20995}
  FIX_3_624509785 = INT32(Round(CONST_SCALE * 3.624509785)); {29692}


{ Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
  For 8-bit samples with the recommended scaling, all the variable
  and constant values involved are no more than 16 bits wide, so a
  16x16->32 bit multiply can be used instead of a full 32x32 multiply.
  For 12-bit samples, a full 32-bit multiplication will be needed. }

{$ifdef BITS_IN_JSAMPLE_IS_8}

   {function Multiply(X, Y: Integer): integer; assembler;
   asm
     mov ax, X
     imul Y
     mov al, ah
     mov ah, dl
   end;}

   {MULTIPLY16C16(var,const)}
   function Multiply(X, Y: Integer): INT32;
   begin
     Multiply := X*INT32(Y);
   end;


{$else}
   function Multiply(X, Y: INT32): INT32;
   begin
     Multiply := X*Y;
   end;
{$endif}


{ Dequantize a coefficient by multiplying it by the multiplier-table
  entry; produce an int result.  In this module, both inputs and result
  are 16 bits or less, so either int or short multiply will work. }

function DEQUANTIZE(coef,quantval : int) : int;
begin
  Dequantize := ( ISLOW_MULT_TYPE(coef) * quantval);
end;


{ Descale and correctly round an INT32 value that's scaled by N bits.
  We assume RIGHT_SHIFT rounds towards minus infinity, so adding
  the fudge factor is correct for either sign of X. }

function DESCALE(x : INT32; n : int) : INT32;
var
  shift_temp : INT32;
begin
{$ifdef RIGHT_SHIFT_IS_UNSIGNED}
  shift_temp := x + (ONE shl (n-1));
  if shift_temp < 0 then
    Descale :=  (shift_temp shr n) or ((not INT32(0)) shl (32-n))
  else
    Descale :=  (shift_temp shr n);
{$else}
  Descale := (x + (ONE shl (n-1)) shr n;
{$endif}
end;

{ Perform dequantization and inverse DCT on one block of coefficients,
  producing a reduced-size 4x4 output block. }

{GLOBAL}
procedure jpeg_idct_4x4 (cinfo : j_decompress_ptr;
                         compptr : jpeg_component_info_ptr;
	                 coef_block : JCOEFPTR;
	                 output_buf : JSAMPARRAY;
                         output_col : JDIMENSION);
type
  PWorkspace = ^TWorkspace;
  TWorkspace = array[0..(DCTSIZE*4)-1] of int; { buffers data between passes }
var
  tmp0, tmp2, tmp10, tmp12 : INT32;
  z1, z2, z3, z4 : INT32;
  inptr : JCOEFPTR;
  quantptr : ISLOW_MULT_TYPE_FIELD_PTR;
  wsptr : PWorkspace;
  outptr : JSAMPROW;
  range_limit : JSAMPROW;
  ctr : int;
  workspace : TWorkspace;	{ buffers data between passes }
  {SHIFT_TEMPS}
var
  dcval : int;
var
  dcval_ : JSAMPLE;
begin
{ Each IDCT routine is responsible for range-limiting its results and
  converting them to unsigned form (0..MAXJSAMPLE).  The raw outputs could
  be quite far out of range if the input data is corrupt, so a bulletproof
  range-limiting step is required.  We use a mask-and-table-lookup method
  to do the combined operations quickly.  See the comments with
  prepare_range_limit_table (in jdmaster.c) for more info. }

  range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE]));

  { Pass 1: process columns from input, store into work array. }

  inptr := coef_block;
  quantptr := ISLOW_MULT_TYPE_FIELD_PTR (compptr^.dct_table);
  wsptr := @workspace;
  for ctr := DCTSIZE downto 1 do
  begin
    { Don't bother to process column 4, because second pass won't use it }
    if (ctr = DCTSIZE-4) then
    begin
      Inc(JCOEF_PTR(inptr));
      Inc(ISLOW_MULT_TYPE_PTR(quantptr));
      Inc(int_ptr(wsptr));

      continue;
    end;
    if ((inptr^[DCTSIZE*1]) or (inptr^[DCTSIZE*2]) or (inptr^[DCTSIZE*3]) or
        (inptr^[DCTSIZE*5]) or (inptr^[DCTSIZE*6]) or (inptr^[DCTSIZE*7]) = 0) then
    begin
      { AC terms all zero; we need not examine term 4 for 4x4 output }
      int(dcval) := DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0]) shl PASS1_BITS;

      wsptr^[DCTSIZE*0] := dcval;
      wsptr^[DCTSIZE*1] := dcval;
      wsptr^[DCTSIZE*2] := dcval;
      wsptr^[DCTSIZE*3] := dcval;

      Inc(JCOEF_PTR(inptr));
      Inc(ISLOW_MULT_TYPE_PTR(quantptr));
      Inc(int_ptr(wsptr));

      continue;
    end;

    { Even part }

    tmp0 := DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0]);
    tmp0 := tmp0 shl (CONST_BITS+1);

    z2 := DEQUANTIZE(inptr^[DCTSIZE*2], quantptr^[DCTSIZE*2]);
    z3 := DEQUANTIZE(inptr^[DCTSIZE*6], quantptr^[DCTSIZE*6]);

    tmp2 := MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865);

    tmp10 := tmp0 + tmp2;
    tmp12 := tmp0 - tmp2;

    { Odd part }

    z1 := DEQUANTIZE(inptr^[DCTSIZE*7], quantptr^[DCTSIZE*7]);
    z2 := DEQUANTIZE(inptr^[DCTSIZE*5], quantptr^[DCTSIZE*5]);
    z3 := DEQUANTIZE(inptr^[DCTSIZE*3], quantptr^[DCTSIZE*3]);
    z4 := DEQUANTIZE(inptr^[DCTSIZE*1], quantptr^[DCTSIZE*1]);

    tmp0 := MULTIPLY(z1, - FIX_0_211164243) { sqrt(2) * (c3-c1) }
	  + MULTIPLY(z2, FIX_1_451774981) { sqrt(2) * (c3+c7) }
	  + MULTIPLY(z3, - FIX_2_172734803) { sqrt(2) * (-c1-c5) }
	  + MULTIPLY(z4, FIX_1_061594337); { sqrt(2) * (c5+c7) }

    tmp2 := MULTIPLY(z1, - FIX_0_509795579) { sqrt(2) * (c7-c5) }
	  + MULTIPLY(z2, - FIX_0_601344887) { sqrt(2) * (c5-c1) }
	  + MULTIPLY(z3, FIX_0_899976223) { sqrt(2) * (c3-c7) }
	  + MULTIPLY(z4, FIX_2_562915447); { sqrt(2) * (c1+c3) }

⌨️ 快捷键说明

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