原创 Delphi JPEG 解码

2008-12-19 23:13 5606 5 6 分类: 工程师职场

implementation


uses  JpegDecode;
{$R *.DFM}


procedure TForm1.Button1Click(Sender: TObject);
var
   fileName:string;
   Bf:BITMAPFILEHEADER;
   MS:TMemoryStream;
   pImg:Pointer;
begin
  if OpenDialog1.Execute then
  begin
     fileName:=OpenDialog1.FileName;
     if LoadJpegFile(FileName,pImg) then
     begin
        MS:=TMemoryStream.Create;
        CopyMemory(@bf,pImg,sizeof(BITMAPFILEHEADER));
        MS.Write(pImg^,bf.BfSize);
        MS.Position:=0;
        Image1.Picture.Bitmap.LoadFromStream(MS);
        MS.Free;
        FreeMem(pImg);
     end else
        ShowMessage('调用失败');
  end;
end;


 


unit JpegDecode;


interface


uses   Windows, SysUtils, Classes, WinTypes;


const
  FUNC_OK = 0;
  FUNC_MEMORY_ERROR = 1;
  FUNC_FILE_ERROR = 2;
  FUNC_FORMAT_ERROR = 3;
  M_SOF0 = $c0;
  M_DHT  = $c4;
  M_EOI  = $d9;
  M_SOS  = $da;
  M_DQT  = $db;
  M_DRI  = $dd;
  M_APP0 = $e0;
  W1     = 2841; // 2048*sqrt(2)*cos(1*pi/16)
  W2     = 2676; // 2048*sqrt(2)*cos(2*pi/16)
  W3     = 2408; // 2048*sqrt(2)*cos(3*pi/16)
  W5     = 1609; // 2048*sqrt(2)*cos(5*pi/16)
  W6     = 1108; // 2048*sqrt(2)*cos(6*pi/16)
  W7     = 565;  // 2048*sqrt(2)*cos(7*pi/16)


  Zig_Zag: array[0..7, 0..7] of Integer =
    ((0, 1, 5, 6, 14, 15, 27, 28),
    (2, 4, 7, 13, 16, 26, 29, 42),
    (3, 8, 12, 17, 25, 30, 41, 43),
    (9, 11, 18, 24, 31, 40, 44, 53),
    (10, 19, 23, 32, 39, 45, 52, 54),
    (20, 22, 33, 38, 46, 51, 55, 60),
    (21, 34, 37, 47, 50, 56, 59, 61),
    (35, 36, 48, 49, 57, 58, 62, 63));


type
  PShortInt = ^Shortint;
  PSmallInt = ^Smallint;
  PLongInt  = ^Longint;
  PByte     = ^Byte;
  PInt      = ^Integer;
  MyInt     = array[0..7, 0..7] of Integer;


function LoadJpegFile(JpegFileName: string; var pImg: Pointer): Boolean;
function InitTag: Integer;
procedure InitTable;
function Decode: Integer;
function DecodeMCUBlock: Integer;
function HufBlock(dchufindex: Byte; achufindex: Byte): Integer;
function DecodeElement: Integer;
procedure IQtIZzMCUComponent(flag: Smallint);
procedure IQtIZzBlock(s: PSmallInt; d: PInt; flag: Smallint);
procedure GetYUV(flag: Smallint);
procedure StoreBuffer;
function ReadByte: Byte;
procedure Initialize_Fast_IDCT;
procedure Fast_IDCT(var block: MyInt);
procedure idctrow(var blk: MyInt);
procedure idctcol(var blk: MyInt);


implementation


var
  //////////////////////////////////////////////////
  ImgWidth: DWORD = 0;
  ImgHeight: DWORD = 0;
  lpImgData: PChar;
  bf: BITMAPFILEHEADER;
  bi: BITMAPINFOHEADER;
  //////////////////////////////////////////////////////////
  SampRate_Y_H, SampRate_Y_V: Smallint;
  SampRate_U_H, SampRate_U_V: Smallint;
  SampRate_V_H, SampRate_V_V: Smallint;
  H_YtoU, V_YtoU, H_YtoV, V_YtoV: Smallint;
  Y_in_MCU, U_in_MCU, V_in_MCU: Smallint;
  lpJpegBuf: PChar;
  lp, lpPtr: PChar;
  qt_table: array[0..2, 0..63] of Smallint;
  comp_num: Smallint;
  comp_index: array[0..3] of Byte;
  YDcIndex, YAcIndex, UVDcIndex, UVAcIndex: Byte;
  HufTabIndex: Byte;
  YQtTable, UQtTable, VQtTable: PSmallInt;
  MyAnd: array[0..8] of Byte = (0, 1, 3, 7, $0f, $1f, $3f, $7f, $ff);
  code_pos_table, code_len_table: array[0..3, 0..15] of Smallint;
  code_value_table: array[0..3, 0..255] of Word;
  huf_max_value, huf_min_value: array [0..3, 0..15] of Word;
  BitPos, CurByte: Smallint;
  rrun, vvalue: Smallint;
  MCUBuffer: array[0..10 * 64 - 1] of Smallint;
  QtZzMCUBuffer: array[0..10 * 64 - 1] of Integer;
  BlockBuffer: array[0..63] of Smallint;
  ycoef, ucoef, vcoef: Smallint;
  IntervalFlag: Boolean;
  Interval: Smallint = 0;
  Y, U, V: array[0..4 * 64 - 1] of Integer;
  sizei, sizej: DWORD;
  restart: Smallint;
  iclip: array[0..1023] of Longint;
  LineBytes, NumColors: DWORD;


  ////////////////////////////////////////////////////////////////
function LoadJpegFile(JpegFileName: string; var pImg: Pointer): Boolean;
var
  fjpg: TFileStream;
  ImgSize: DWORD;
  JpegBufSize: DWORD;
  funcret: Integer;
  lpImgDataTemp: PChar;
begin
  fjpg := TFileStream.Create(JpegFileName, fmOpenRead);
  //将Jpeg文件读入内存
  JpegBufSize := fjpg.Size;
  GetMem(lpJpegBuf, JpegBufSize);
  fjpg.Read(lpJpegBuf^, JpegBufSize);
  fjpg.Free;


  InitTable;
  funcret := InitTag;
  if (funcret <> FUNC_OK) then        //初始化表头不成功
  begin
    FreeMem(lpJpegBuf, JpegBufSize);
    Result := false;
    Exit;
  end;
  bi.biSize := SizeOf(BITMAPINFOHEADER);  //定义BMP头
  bi.biWidth := ImgWidth;
  bi.biHeight := ImgHeight;
  bi.biPlanes := 1;
  bi.biBitCount := 24;
  bi.biClrUsed := 0;
  bi.biClrImportant := 0;
  bi.biCompression := BI_RGB;
  NumColors := 0;
  LineBytes := DWORD((bi.biWidth * bi.biBitCount + 31) div 32 * 4);
  ImgSize := LineBytes * DWORD(bi.biHeight); //变化后的图象空间
  bf.bfType := $4d42;                        //'BM'
  bf.bfSize := SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPINFOHEADER)
    + NumColors * SizeOf(RGBQUAD) + ImgSize;
  bf.bfOffBits := DWORD(NumColors * SizeOf(RGBQUAD) +
    SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPINFOHEADER));


  GetMem(lpImgData, bf.bfSize);  //分配变换后的存储空间
  lpImgDataTemp := lpImgData;
  CopyMemory(lpImgDataTemp, @bf, SizeOf(BITMAPFILEHEADER));
  lpImgDataTemp := lpImgDataTemp + SizeOf(BITMAPFILEHEADER);
  CopyMemory(lpImgDataTemp, @bi, SizeOf(BITMAPINFOHEADER));
  lpPtr := lpImgData + bf.bfOffBits;              //实际图象数据位置


  if ((SampRate_Y_H = 0) or (SampRate_Y_V = 0)) then
  begin
    FreeMem(lpJpegBuf);
    FreeMem(lpImgData);
    Result := false;
    Exit;
  end;


  funcret := Decode;
  if (funcret = FUNC_OK) then        //解码成功
  begin
    Result := true;
    pImg   := lpImgData;
    FreeMem(lpJpegBuf);
    Exit;
  end
  else
  begin
    FreeMem(lpImgData);
    FreeMem(lpJpegBuf);
    Result := false;
    Exit;
  end;
end;
////////////////////////////////////////////////////////////////////////////////


function InitTag: Integer;
var
  finish: Boolean;
  id: Byte;
  llength: Smallint;
  i, j, k: Smallint;
  huftab1, huftab2: Smallint;
  huftabindex: Smallint;
  hf_table_index: Byte;
  qt_table_index: Byte;
  comnum: Byte;
  lptemp: PChar;
  ccount: Smallint;
begin
  finish := false;
  lp := lpJpegBuf + 2;//跳过两个字节SOI(0xFF,0xD8 Start of Image)


  while (not finish) do
  begin
    id := Byte((lp + 1)^);  //取出低位字节(高位在前,低位在后)
    lp := lp + 2;           //跳过取出的字节
    case id of
      M_APP0:   //JFIF APP0 segment marker (0xE0)
      begin
        llength := MAKEWORD(Byte((lp + 1)^), Byte(lp^));
        //MAKEWORD 转换Motorlora 与 intel 数据格式
        lp := lp + llength;//Skip JFIF segment marker
      end;
      M_DQT:   //定义量化表(0xFF,0xDB)
      begin
        llength := MAKEWORD(Byte((lp + 1)^), Byte(lp^));//(量化表长度)
        qt_table_index := (Byte((lp + 2)^) and $0f);
        //量化表信息bit 0..3: QT 号(0..3, 否则错误)
        //bit 4..7: QT 精度, 0 = 8 bit, 否则 16 bit
        lptemp := lp + 3;
        //n 字节的 QT, n = 64*(精度+1)
        if (llength < 80) then               //精度为 8 bit
        begin
          for i := 0 to 63 do
          begin
            qt_table[qt_table_index, i] := Smallint(lptemp^);
            Inc(lptemp);
          end;
        end
        else                         //精度为 16 bit
        begin
          for i := 0 to 63 do
          begin
            qt_table[qt_table_index, i] :=
              Smallint(lptemp^);
            Inc(lptemp);
          end;
          qt_table_index := Byte(lptemp^) and $0f;
          Inc(lptemp);
          for i := 0 to 63 do
          begin
            qt_table[qt_table_index, i] := Smallint(lptemp^);
            Inc(lptemp);
          end;
        end;
        lp := lp + llength; //跳过量化表
      end;
      M_SOF0:   //帧开始 (baseline JPEG 0xFF,0xC0)
      begin
        llength := MAKEWORD(Byte((lp + 1)^), Byte(lp^));
        //长度 (高字节, 低字节), 8+components*3
        ImgHeight := MAKEWORD(Byte((lp + 4)^), Byte((lp + 3)^));
        //图片高度 (高字节, 低字节), 如果不支持 DNL 就必须 >0
        ImgWidth := MAKEWORD(Byte((lp + 6)^), Byte((lp + 5)^));
        //图片宽度 (高字节, 低字节), 如果不支持 DNL 就必须 >0
        comp_num := Byte((lp + 7)^);
        //components 数量(1 byte), 灰度图是 1, YCbCr/YIQ 彩色图是 3, CMYK 彩色图是 4
        if ((comp_num <> 1) and (comp_num <> 3)) then
        begin
          Result := FUNC_FORMAT_ERROR;
          Exit;
        end;
        if (comp_num = 3) then                  //YCbCr/YIQ 彩色图
        begin
          comp_index[0] := Byte((lp + 8)^);
          //component id (1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q)
          SampRate_Y_H := Byte((lp + 9)^) shr 4;      //水平采样系数
          SampRate_Y_V := Byte((lp + 9)^) and $0f;    //水平采样系数
          YQtTable := PSmallInt(@qt_table[Byte((lp + 10)^)]);
          //通过量化表号取得量化表地址
          ///  ShowMessage(IntToStr(YQtTable^));
          comp_index[1] := Byte((lp + 11)^);         //component id
          SampRate_U_H := Byte((lp + 12)^) shr 4;     //水平采样系数
          SampRate_U_V := Byte((lp + 12)^) and $0f;   //水平采样系数
          UQtTable := PSmallInt(@qt_table[Byte((lp + 13)^)]);
          //通过量化表号取得量化表地址
          comp_index[2] := Byte((lp + 14)^);         //component id
          SampRate_V_H := Byte((lp + 15)^) shr 4;     //水平采样系数
          SampRate_V_V := Byte((lp + 15)^) and $0f;   //水平采样系数
          VQtTable := PSmallInt(@qt_table[Byte((lp + 16)^)]);
          //通过量化表号取得量化表地址
        end
        else                                       //灰度图
        begin
          comp_index[0] := Byte((lp + 8)^);
          SampRate_Y_H := Byte((lp + 9)^) shr 4;
          SampRate_Y_V := Byte((lp + 9)^) and $0f;
          YQtTable := PSmallInt(@qt_table[Byte((lp + 10)^)]);
          //灰度图的量化表都一样


          comp_index[1] := Byte((lp + 8)^);
          SampRate_U_H := 1;
          SampRate_U_V := 1;
          UQtTable := PSmallInt(@qt_table[Byte((lp + 10)^)]);


          comp_index[2] := Byte((lp + 8)^);
          SampRate_V_H := 1;
          SampRate_V_V := 1;
          VQtTable := PSmallInt(@qt_table[Byte((lp + 10)^)]);
        end;
        lp := lp + llength;
      end;
      M_DHT:   //定义 Huffman Table(0xFF,0xC4)
      begin
        llength := MAKEWORD(Byte((lp + 1)^), Byte(lp^));
        //长度 (高字节, 低字节)
        if (llength < $d0) then               // Huffman Table信息 (1 byte)
        begin
          huftab1 := Smallint(Byte((lp + 2)^) shr 4);
          //huftab1=0,1(HT 类型,0 = DC 1 = AC)
          huftab2 := Smallint(Byte((lp + 2)^) and $0f);
          //huftab2=0,1(HT 号  ,0 = Y  1 = UV)
          huftabindex := huftab1 * 2 + huftab2;
          //0 = YDC 1 = UVDC 2 = YAC 3 = UVAC
          lptemp := lp + 3;
          for i := 0 to 15 do                     //16 bytes: 长度是 1..16 代码的符号数
          begin
            code_len_table[huftabindex, i] := Smallint(lptemp^);//码长为
            Inc(lptemp);
            //i的码字个数
          end;
          j := 0;
          for i := 0 to 15 do             //得出HT的所有码字的对应值
          begin
            if (code_len_table[huftabindex, i] <> 0) then
            begin
              k := 0;
              while (k < code_len_table[huftabindex, i]) do
              begin
                code_value_table[huftabindex, k + j] := Smallint(lptemp^);
                lptemp := lptemp + 1;
                k := k + 1;
              end;
              j := j + k;
            end;
          end;
          i := 0;
          while (code_len_table[huftabindex, i] = 0) do //去掉代码的符号数为零
            i := i + 1;
          for j := 0 to i - 1 do
          begin
            huf_min_value[huftabindex, j] := 0;            //码长为j的最小码字
            huf_max_value[huftabindex, j] := 0;            //码长为j的最大码字
          end;
          huf_min_value[huftabindex, i] := 0;
          huf_max_value[huftabindex, i] := code_len_table[huftabindex, i] - 1;
          for j := i + 1 to 15 do
          begin
            //码长为j的最小码字与最大码字
            huf_min_value[huftabindex, j] :=
              (huf_max_value[huftabindex, j - 1] + 1) shl 1;
            huf_max_value[huftabindex, j] :=
              huf_min_value[huftabindex, j] + code_len_table[huftabindex, j] - 1;
          end;
          code_pos_table[huftabindex, 0] := 0; //码起始位置
          for j := 1 to 15 do
            code_pos_table[huftabindex, j] :=
              code_len_table[huftabindex, j - 1] + code_pos_table[huftabindex, j - 1];
          lp := lp + llength;
        end  //if
        else
        begin
          hf_table_index := Byte((lp + 2)^);
          lp := lp + 2;
          while (hf_table_index <> $ff) do
          begin
            huftab1 := Smallint(hf_table_index shr 4);     //huftab1=0,1
            huftab2 := Smallint(hf_table_index and $0f);   //huftab2=0,1
            huftabindex := huftab1 * 2 + huftab2;
            lptemp := lp;
            Inc(lptemp);
            ccount := 0;
            for i := 0 to 15 do
            begin
              code_len_table[huftabindex, i] :=
                Smallint(lptemp^);
              Inc(lptemp);
              ccount := ccount + code_len_table[huftabindex, i];
            end;
            ccount := ccount + 17;
            j := 0;
            for i := 0 to 15 do
              if (code_len_table[huftabindex, i] <> 0) then
              begin
                k := 0;
                while (k < code_len_table[huftabindex, i]) do
                begin
                  code_value_table[huftabindex, k + j] := Smallint(lptemp^);
                  Inc(lptemp);
                  Inc(k);
                end;
                j := j + k;
              end;
            i := 0;
            while (code_len_table[huftabindex, i] = 0) do
              Inc(i);
            for j := 0 to i - 1 do
            begin
              huf_min_value[huftabindex, j] := 0;
              huf_max_value[huftabindex, j] := 0;
            end;
            huf_min_value[huftabindex, i] := 0;
            huf_max_value[huftabindex, i] := code_len_table[huftabindex, i] - 1;
            for j := i + 1 to 15 do
            begin
              huf_min_value[huftabindex, j] :=
                (huf_max_value[huftabindex, j - 1] + 1) shl 1;
              huf_max_value[huftabindex, j] :=
                huf_min_value[huftabindex, j] + code_len_table[huftabindex, j] - 1;
            end;
            code_pos_table[huftabindex, 0] := 0;
            for j := 1 to 15 do
              code_pos_table[huftabindex, j] :=
                code_len_table[huftabindex, j - 1] + code_pos_table[huftabindex, j - 1];
            lp := lp + ccount;
            hf_table_index := Byte(lp^);
          end;  //while
        end;    //else
      end;
      M_DRI: //定义重新开始间隔, 细节附后
      begin
        llength := MAKEWORD(Byte((lp + 1)^), Byte(lp^));
        restart := MAKEWORD(Byte((lp + 3)^), Byte((lp + 2)^));
        lp := lp + llength;
      end;
      M_SOS: //扫描行开始0xff, 0xda (SOS)
      begin
        llength := MAKEWORD(Byte((lp + 1)^), Byte(lp^));//长度 (高字节, 低字节),
        comnum := Byte((lp + 2)^);
        //扫描行内组件的数量 (1 byte), 必须 >:= 1 , <:=4 (否则是错的) 通常是 3
        if (comnum <> comp_num) then
        //必须是 6+2*(扫描行内组件的数量)
        begin
          Result := FUNC_FORMAT_ERROR;
          Exit;
        end;
        lptemp := lp + 3;
        for i := 0 to comp_num - 1 do
        begin                   //每组件的信息
          if (Byte(lptemp^) = comp_index[0]) then
          begin  //1 byte :Component id
            YDcIndex := Byte((lptemp + 1)^) shr 4;   //Y 使用的 Huffman 表
            YAcIndex := (Byte((lptemp + 1)^) and $0f) + 2;
          end
          else
          begin
            UVDcIndex := Byte((lptemp + 1)^) shr 4;   //U,V
            UVAcIndex := (Byte((lptemp + 1)^) and $0f) + 2;
          end;
          lptemp := lptemp + 2;
        end;  // for
        lp := lp + llength;
        finish := true;
      end;
      M_EOI:    //图片结束
      begin
        Result := FUNC_FORMAT_ERROR;
        Exit;
      end;
      else
      begin
        if ((id and $f0) <> $d0) then
        begin
          llength := MAKEWORD(Byte((lp + 1)^), Byte(lp^));
          lp := lp + llength;
        end
        else
          lp := lp + 2;
      end;
    end;
  end; //while
  Result := FUNC_OK;
end;
/////////////////////////////////////////////////////////////////


procedure InitTable;
var
  i, j: Smallint;
begin
  sizei := 0;
  sizej := 0;
  ImgWidth := 0;
  ImgHeight := 0;
  rrun := 0;
  vvalue := 0;
  BitPos := 0;
  CurByte := 0;
  IntervalFlag := false;
  restart := 0;
  for i := 0 to 2 do
    for j := 0 to 63 do
      qt_table[i, j] := 0;           //量化表
  comp_num := 0;
  HufTabIndex := 0;
  for i := 0 to 2 do
    comp_index := 0;
  for i := 0 to 3 do
    for j := 0 to 15 do
    begin
      code_len_table[i, j] := 0;
      code_pos_table[i, j] := 0;
      huf_max_value[i, j] := 0;
      huf_min_value[i, j] := 0;
    end;
  for i := 0 to 3 do
    for j := 0 to 255 do
      code_value_table[i, j] := 0;


  for i := 0 to 10 * 64 - 1 do
  begin
    MCUBuffer     := 0;
    QtZzMCUBuffer := 0;
  end;
  for i := 0 to 63 do
  begin
    Y           := 0;
    U           := 0;
    V           := 0;
    BlockBuffer := 0;
  end;
  ycoef := 0;
  ucoef := 0;
  vcoef := 0;
end;
  /////////////////////////////////////////////////////////////////////////
  //调用顺序: Initialize_Fast_IDCT() :初始化
  //          DecodeMCUBlock()       Huffman Decode
  //          IQtIZzMCUComponent()   反量化、反DCT
  //          GetYUV()               Get Y U V
  //          StoreBuffer()          YUV to RGB
  /////////////////////////////////////////////////////////////////////////


function Decode: Integer;
var
  funcret: Integer;
begin
  Y_in_MCU := SampRate_Y_H * SampRate_Y_V;     //YDU YDU YDU YDU
  U_in_MCU := SampRate_U_H * SampRate_U_V;     //cRDU
  V_in_MCU := SampRate_V_H * SampRate_V_V;     //cBDU
  H_YtoU := SampRate_Y_H div SampRate_U_H;
  V_YtoU := SampRate_Y_V div SampRate_U_V;
  H_YtoV := SampRate_Y_H div SampRate_V_H;
  V_YtoV := SampRate_Y_V div SampRate_V_V;
  Initialize_Fast_IDCT;
  funcret := DecodeMCUBlock;
  while (funcret = FUNC_OK) do
  begin                                           //After Call DecodeMCUBUBlock()
    Inc(Interval);                                //The Digital has been Huffman Decoded and
    if ((restart <> 0) and ((Interval mod restart) = 0)) then
      //be stored in MCUBuffer(YDU,YDU,YDU,YDU
      IntervalFlag := true                          // UDU,VDU) Every DU := 8*8
    else
      IntervalFlag := false;
    IQtIZzMCUComponent(0);   //反量化 and IDCT The Data in QtZzMCUBuffer
    IQtIZzMCUComponent(1);
    IQtIZzMCUComponent(2);
    GetYUV(0);                    //得到Y cR cB
    GetYUV(1);
    GetYUV(2);
    StoreBuffer;               //To RGB
    sizej := sizej + DWORD(SampRate_Y_H * 8);
    if (sizej >= ImgWidth) then
    begin
      sizej := 0;
      sizei := sizei + DWORD(SampRate_Y_V * 8);
    end;
    if ((sizej = 0) and (sizei >= ImgHeight)) then
      Break;
    funcret := DecodeMCUBlock;
  end;//while
  Result := funcret;
end;
  ////////////////////////////////////////////////////////////////////////////////
  // 入口 QtZzMCUBuffer 出口 Y[] U[] V[]
  ////////////////////////////////////////////////////////////////////////////////


procedure GetYUV(flag: Smallint);
var
  H, VV: Smallint;
  Temp: Integer;
  i, j, k, hk: Smallint;
  buf, tempbuf: Pint;
  pQtZzMCU: Pint;
begin
  case flag of
    0:                             //亮度分量
    begin
      H := SampRate_Y_H;
      VV := SampRate_Y_V;
      buf := @Y;
      pQtZzMCU := Pint(@QtZzMCUBuffer);
    end;
    1:                             //红色分量
    begin
      H := SampRate_U_H;
      VV := SampRate_U_V;
      buf := @U;
      pQtZzMCU := Pint(@QtZzMCUBuffer);
      Inc(pQtZzMCU, Y_in_MCU * 64);
    end;
    2:                            //蓝色分量
    begin
      H := SampRate_V_H;
      VV := SampRate_V_V;
      buf := @V;
      pQtZzMCU := Pint(@QtZzMCUBuffer);
      Inc(pQtZzMCU, (Y_in_MCU + U_in_MCU) * 64);
    end;
    else
    begin
      H := 0;
      VV := 0;
      buf := nil;
      pQtZzMCU := nil;
    end;
  end;//end case
  for i := 0 to VV - 1 do
    for j := 0 to H - 1 do
      for k := 0 to 7 do
        for hk := 0 to 7 do
        begin
          Temp := (i * 8 + k) * SampRate_Y_H * 8 + j * 8 + hk;
          tempbuf := buf;
          Inc(tempbuf, Temp);
          tempbuf^ := Integer(pQtZzMCU^);
          Inc(pQtZzMCU);
        end;
end;
  ///////////////////////////////////////////////////////////////////////////////
  //将解出的字按RGB形式存储 lpbmp (BGR),(BGR) ......入口Y[] U[] V[] 出口lpPtr
  ///////////////////////////////////////////////////////////////////////////////


procedure StoreBuffer;
var
  i, j: Smallint;
  lpbmp: PChar;
  R, G, B: Byte;
  yy, uu, vv, rr, gg, bb: Integer;
begin
  for i := 0 to SampRate_Y_V * 8 - 1 do
  begin                                  // sizei表示行 sizej 表示列
    if ((sizei + DWORD(i)) < ImgHeight) then
    begin
      lpbmp := lpPtr + DWORD((ImgHeight - sizei - DWORD(i) - 1) *
        LineBytes + sizej * 3);
      for j := 0 to SampRate_Y_H * 8 - 1 do
      begin
        if ((sizej + DWORD(j)) < ImgWidth) then
        begin
          yy := Y[i * 8 * SampRate_Y_H + j];
          uu := U[(i div V_YtoU) * 8 * SampRate_Y_H + j div H_YtoU];  //内插
          vv := V[(i div V_YtoV) * 8 * SampRate_Y_H + j div H_YtoV];
          rr := ((yy shl 8) + 18 * uu + 367 * vv);
          if rr < 0 then
            rr :=
              (rr shr 8) or (not (Integer(0)) shl (32 - 8))
          else
            rr := rr shr 8;
          gg := ((yy shl 8) - 159 * uu - 220 * vv);
          if gg < 0 then
            gg :=
              (gg shr 8) or (not (Integer(0)) shl (32 - 8))
          else
            gg := gg shr 8;
          bb := ((yy shl 8) + 411 * uu - 29 * vv);
          if bb < 0 then
            bb :=
              (bb shr 8) or (not (Integer(0)) shl (32 - 8))
          else
            bb := bb shr 8;
          R := Byte(rr);
          G := Byte(gg);
          B := Byte(bb);
          if ((rr and $ffffff00) <> 0) then
            if (rr > 255) then
              R := 255
            else if (rr < 0) then
              R := 0;
          if (gg and $ffffff00 <> 0) then
            if (gg > 255) then
              G := 255
            else if (gg < 0) then
              G := 0;
          if (bb and $ffffff00 <> 0) then
            if (bb > 255) then
              B := 255
            else if (bb < 0) then
              B := 0;
          lpbmp^ := Char(B);
          Inc(lpbmp);
          lpbmp^ := Char(G);
          Inc(lpbmp);
          lpbmp^ := Char(R);
          Inc(lpbmp);
        end
        else
          Break;
      end;
    end
    else
      Break;
  end;
end;
  ///////////////////////////////////////////////////////////////////////////////
  //Huffman Decode   MCU 出口 MCUBuffer  入口Blockbuffer[  ]
  ///////////////////////////////////////////////////////////////////////////////


function DecodeMCUBlock: Integer;
var
  lpMCUBuffer: PSmallInt;
  i, j: Smallint;
  funcret: Integer;
begin
  if (IntervalFlag) then
  begin
    Inc(lp, 2);
    ycoef   := 0;   //差值复位
    ucoef   := 0;
    vcoef   := 0;
    BitPos  := 0;
    CurByte := 0;
  end;
  case comp_num of
         //comp_num 指图的类型(彩色图、灰度图)
    3:   //彩色图
    begin
      lpMCUBuffer := @MCUBuffer;
      for i := 0 to SampRate_Y_H * SampRate_Y_V - 1 do  //Y
      begin
        funcret := HufBlock(YDcIndex, YAcIndex);   //解码4 * (8*8)
        if (funcret <> FUNC_OK) then
        begin
          Result := funcret;
          Exit;
        end;
        BlockBuffer[0] := BlockBuffer[0] + ycoef;
        //直流分量是差值,所以要累加。
        ycoef := BlockBuffer[0];
        for j := 0 to 63 do
        begin
          lpMCUBuffer^ := BlockBuffer[j];
          Inc(lpMCUBuffer);
        end;
      end;
      for i := 0 to SampRate_U_H * SampRate_U_V - 1 do  //U
      begin
        funcret := HufBlock(UVDcIndex, UVAcIndex);
        if (funcret <> FUNC_OK) then
        begin
          Result := funcret;
          Exit;
        end;
        BlockBuffer[0] := BlockBuffer[0] + ucoef;
        ucoef := BlockBuffer[0];
        for j := 0 to 63 do
        begin
          lpMCUBuffer^ := BlockBuffer[j];
          Inc(lpMCUBuffer);
        end;
      end;
      for i := 0 to SampRate_V_H * SampRate_V_V - 1 do  //V
      begin
        funcret := HufBlock(UVDcIndex, UVAcIndex);
        if (funcret <> FUNC_OK) then
        begin
          Result := funcret;
          Exit;
        end;
        BlockBuffer[0] := BlockBuffer[0] + vcoef;
        vcoef := BlockBuffer[0];
        for j := 0 to 63 do
        begin
          lpMCUBuffer^ := BlockBuffer[j];
          Inc(lpMCUBuffer);
        end;
      end;
    end;
    1:   //Gray Picture
    begin
      lpMCUBuffer := @MCUBuffer;
      funcret := HufBlock(YDcIndex, YAcIndex);
      if (funcret <> FUNC_OK) then
      begin
        Result := funcret;
        Exit;
      end;
      BlockBuffer[0] := BlockBuffer[0] + ycoef;
      ycoef := BlockBuffer[0];
      for j := 0 to 63 do
      begin
        lpMCUBuffer^ := BlockBuffer[j];
        Inc(lpMCUBuffer);
      end;
      for i := 0 to 127 do
      begin
        lpMCUBuffer^ := 0;
        Inc(lpMCUBuffer);
      end;
    end;
    else
    begin
      Result := FUNC_FORMAT_ERROR;
      Exit;
    end;
  end;//case
  Result := FUNC_OK;
end;
  //////////////////////////////////////////////////////////////////
  //Huffman Decode (8*8) DU   出口 Blockbuffer[ ] 入口 vvalue
  //////////////////////////////////////////////////////////////////


function HufBlock(dchufindex: Byte; achufindex: Byte): Integer;
var
  Count: Smallint;
  i: Smallint;
  funcret: Integer;
begin
  Count := 0;
  //dc
  HufTabIndex := dchufindex;
  funcret := DecodeElement;  //Read Byte Dc
  if (funcret <> FUNC_OK) then
  begin
    Result := funcret;
    Exit;
  end;
  BlockBuffer[Count] := vvalue;//解出的直流系数
  Inc(Count);
  //ac
  HufTabIndex := achufindex;
  while (Count < 64) do
  begin         //63 Bytes AC
    funcret := DecodeElement;
    if (funcret <> FUNC_OK) then
    begin
      Result := funcret;
      Exit;
    end;
    if ((rrun = 0) and (vvalue = 0)) then
    begin
      for i := Count to 63 do
        BlockBuffer := 0;
      Count := 64;
    end
    else
    begin
      for i := 0 to rrun - 1 do    //前面的零
      begin
        BlockBuffer[Count] := 0;
        Inc(Count);
      end;
      BlockBuffer[Count] := vvalue;//解出的值
      Inc(Count);
    end;
  end;
  Result := FUNC_OK;
end;
  //////////////////////////////////////////////////////////////////////////////
  //Huffman 解码  每个元素   出口 vvalue 入口 读文件ReadByte
  //////////////////////////////////////////////////////////////////////////////


function DecodeElement: Integer;
var
  thiscode, tempcode: Integer;
  Temp, valueex: Word;
  codelen: Smallint;
  hufexbyte, runsize, tempsize, sign: Byte;
  newbyte, lastbyte: Byte;
begin
  if (BitPos >= 1) then            //BitPos指示当前比特位置
  begin
    Dec(BitPos);
    thiscode := Byte(CurByte shr BitPos);  //取一个比特
    CurByte  := CurByte and MyAnd[BitPos]; //清除取走的比特位
  end
  else                                        //取出的一个字节已用完
  begin                                       //新取
    lastbyte := ReadByte; //读出一个字节
    Dec(BitPos);                     //and[]:=0x0,0x1,0x3,0x7,0xf,0x1f,0x2f,0x3f,0x4f
    newbyte  := CurByte and MyAnd[BitPos];  //
    thiscode := lastbyte shr 7;
    CurByte  := newbyte;
  end;
  codelen := 1;
  //与Huffman表中的码字匹配,直自找到为止
  while ((thiscode < huf_min_value[HufTabIndex, codelen - 1]) or
    (code_len_table[HufTabIndex, codelen - 1] = 0) or
    (thiscode > huf_max_value[HufTabIndex, codelen - 1])) do
  begin
    if (BitPos >= 1) then
    begin  //取出的一个字节还有
      Dec(BitPos);
      tempcode := Byte(CurByte shr BitPos);
      CurByte := CurByte and MyAnd[BitPos];
    end
    else
    begin
      lastbyte := ReadByte;
      Dec(BitPos);
      newbyte := CurByte and MyAnd[BitPos];
      tempcode := Byte(lastbyte shr 7);
      CurByte := newbyte;
    end;
    thiscode := (thiscode shl 1) + tempcode;
    Inc(codelen);
    if (codelen > 16) then
    begin
      Result := FUNC_FORMAT_ERROR;
      Exit;
    end;
  end;  //while
  Temp := thiscode - huf_min_value[HufTabIndex, codelen - 1] +
    code_pos_table[HufTabIndex, codelen - 1];
  hufexbyte := Byte(code_value_table[HufTabIndex, Temp]);
  rrun := Smallint(hufexbyte shr 4);  //一个字节中,高四位是其前面的零的个数。
  runsize := hufexbyte and $0f;       //后四位为后面字的尺寸
  if (runsize = 0) then
  begin
    vvalue := 0;
    Result := FUNC_OK;
    Exit;
  end;
  tempsize := runsize;
  if (BitPos >= runsize) then
  begin
    BitPos  := BitPos - runsize;
    valueex := Byte(CurByte shr BitPos);
    CurByte := CurByte and MyAnd[BitPos];
  end
  else
  begin
    valueex  := CurByte;
    tempsize := tempsize - BitPos;
    while (tempsize > 8) do
    begin
      lastbyte := ReadByte;
      valueex := (valueex shl 8) + Byte(lastbyte);
      tempsize := tempsize - 8;
    end;  //while
    lastbyte := ReadByte;
    BitPos   := BitPos - tempsize;
    valueex  := (valueex shl tempsize) + (lastbyte shr BitPos);
    CurByte  := lastbyte and MyAnd[BitPos];
  end;  //else
  sign := valueex shr (runsize - 1);
  if (sign <> 0) then
    vvalue := valueex             //解出的码值
  else
  begin
    valueex := valueex xor $ffff;
    Temp    := $ffff shl runsize;
    vvalue  := -Smallint(valueex xor Temp);
  end;
  Result := FUNC_OK;
end;


  /////////////////////////////////////////////////////////////////////////////////////
  //反量化MCU中的每个组件   入口 MCUBuffer 出口 QtZzMCUBuffer
  /////////////////////////////////////////////////////////////////////////////////////
procedure IQtIZzMCUComponent(flag: Smallint);
var
  H, VV: Smallint;
  i, j: Smallint;
  pQtZzMCUBuffer, tempbuf1: Pint;
  pMCUBuffer, tempbuf2: PSmallInt;
begin
  case flag of
    0:
    begin
      H := SampRate_Y_H;
      VV := SampRate_Y_V;
      pMCUBuffer := PSmallInt(@MCUBuffer);  //Huffman Decoded
      pQtZzMCUBuffer := Pint(@QtZzMCUBuffer);
    end;
    1:
    begin
      H := SampRate_U_H;
      VV := SampRate_U_V;
      pMCUBuffer := PSmallInt(@MCUBuffer);
      Inc(pMCUBuffer, Y_in_MCU * 64);
      pQtZzMCUBuffer := Pint(@QtZzMCUBuffer);
      Inc(pQtZzMCUBuffer, Y_in_MCU * 64);
    end;
    2:
    begin
      H := SampRate_V_H;
      VV := SampRate_V_V;
      pMCUBuffer := PSmallInt(@MCUBuffer);
      Inc(pMCUBuffer, (Y_in_MCU + U_in_MCU) * 64);
      pQtZzMCUBuffer := Pint(@QtZzMCUBuffer);
      Inc(pQtZzMCUBuffer, (Y_in_MCU + U_in_MCU) * 64);
    end;
    else
    begin
      H := 0;
      pQtZzMCUBuffer := nil;
      pMCUBuffer := nil;
      VV := 0;
    end;
  end;//case
  for i := 0 to VV - 1 do
    for j := 0 to H - 1 do
    begin
      tempbuf2 := pMCUBuffer;
      Inc(tempbuf2, (i * H + j) * 64);
      tempbuf1 := pQtZzMCUBuffer;
      Inc(tempbuf1, (i * H + j) * 64);
      IQtIZzBlock(tempbuf2, tempbuf1, flag);      //8*8DU
    end;
end;
             //要量化的字
  //////////////////////////////////////////////////////////////////////////////////////////
  //反量化 8*8 DU
  //////////////////////////////////////////////////////////////////////////////////////////


procedure IQtIZzBlock(s: PSmallInt; d: PInt; flag: Smallint);
var
  i, j: Smallint;
  tag: Smallint;
  pQt, temp1, temp3: PSmallInt;
  buffer2: MyInt;
  temp2: Pint;
  offset: Smallint;
begin
  case flag of
    0:                //亮度
    begin
      pQt := YQtTable;      //量化表地址
      //            ShowMessage(IntTostr(YQtTable^));
      offset := 128;
    end;
    1:                //红
    begin
      pQt := UQtTable;
      offset := 0;
    end;
    2:               //蓝
    begin
      pQt := VQtTable;
      offset := 0;
    end;
    else
      pQt := nil;
      offset := 0;
  end;


  for i := 0 to 7 do
    for j := 0 to 7 do
    begin
      tag := Zig_Zag[i, j];
      temp1 := s;
      Inc(temp1, tag);
      temp3 := pQt;
      Inc(temp3, tag);
      buffer2[i, j] := Integer(temp1^ * temp3^);
    end;
  Fast_IDCT(buffer2);    //反DCT
  for i := 0 to 7 do
    for j := 0 to 7 do
    begin
      temp2 := d;
      Inc(temp2, i * 8 + j);
      temp2^ := buffer2[i, j] + offset;
    end;
end;
///////////////////////////////////////////////////////////////////////////////


procedure Fast_IDCT(var block: MyInt);
begin
  idctrow(block);
  idctcol(block);
end;
///////////////////////////////////////////////////////////////////////////////


function ReadByte: Byte;
var
  i: Byte;
begin
  i := Byte(lp^); // lp 为解码的起始位置
  lp := lp + 1;
  if (i = $ff) then
    lp := lp + 1;
  BitPos := 8;
  CurByte := i;
  Result := i;
end;
///////////////////////////////////////////////////////////////////////


procedure Initialize_Fast_IDCT;
var
  i: Smallint;
begin
  for i := -512 to 511 do
  begin
    if i<-256 then
      iclip[512 + i] := -256;
    if i > 255 then
      iclip[512 + i] := 255;
    if (i >= -256) and (i <= 255) then
      iclip[512 + i] := i;
  end;
end;
////////////////////////////////////////////////////////////////////////


procedure idctrow(var blk: MyInt);
var
  i, x0, x1, x2, x3, x4, x5, x6, x7, x8: Integer;
begin
  //intcut
  for i := 0 to 7 do
  begin
    x1 := blk[i, 4] shl 11;
    x2 := blk[i, 6];
    x3 := blk[i, 2];
    x4 := blk[i, 1];
    x5 := blk[i, 7];
    x6 := blk[i, 5];
    x7 := blk[i, 3];
    if ((x1 or x2 or x3 or x4 or x5 or x6 or x7) = 0) then
    begin
      blk[i, 1] := blk[i, 0] shl 3;
      blk[i, 2] := blk[i, 0] shl 3;
      blk[i, 3] := blk[i, 0] shl 3;
      blk[i, 4] := blk[i, 0] shl 3;
      blk[i, 5] := blk[i, 0] shl 3;
      blk[i, 6] := blk[i, 0] shl 3;
      blk[i, 7] := blk[i, 0] shl 3;
      blk[i, 0] := blk[i, 0] shl 3;
      Continue;
    end;
    x0 := (blk[i, 0] shl 11) + 128; // for proper rounding in the fourth stage
    //first stage
    x8 := W7 * (x4 + x5);
    x4 := x8 + (W1 - W7) * x4;
    x5 := x8 - (W1 + W7) * x5;
    x8 := W3 * (x6 + x7);
    x6 := x8 - (W3 - W5) * x6;
    x7 := x8 - (W3 + W5) * x7;
    //second stage
    x8 := x0 + x1;
    x0 := x0 - x1;
    x1 := W6 * (x3 + x2);
    x2 := x1 - (W2 + W6) * x2;
    x3 := x1 + (W2 - W6) * x3;
    x1 := x4 + x6;
    x4 := x4 - x6;
    x6 := x5 + x7;
    x5 := x5 - x7;
    //third stage
    x7 := x8 + x3;
    x8 := x8 - x3;
    x3 := x0 + x2;
    x0 := x0 - x2;
    if (181 * (x4 + x5) + 128) < 0 then
      x2 := ((181 * (x4 + x5) + 128) shr 8) or
        ((not Integer(0)) shl (32 - 8))
    else
      x2 := (181 * (x4 + x5) + 128) shr 8;
    if (181 * (x4 - x5) + 128) < 0 then
      x4 := ((181 * (x4 - x5) + 128) shr 8) or
        ((not Integer(0)) shl (32 - 8))
    else
      x4 := (181 * (x4 - x5) + 128) shr 8;
    //fourth stage
    if x7 + x1 < 0 then
      blk[i, 0] := ((x7 + x1) shr 8) or ((not Integer(0)) shl (32 - 8))
    else
      blk[i, 0] := (x7 + x1) shr 8;
    if x3 + x2 < 0 then
      blk[i, 1] := ((x3 + x2) shr 8) or ((not Integer(0)) shl (32 - 8))
    else
      blk[i, 1] := (x3 + x2) shr 8;
    if x0 + x4 < 0 then
      blk[i, 2] := ((x0 + x4) shr 8) or ((not Integer(0)) shl (32 - 8))
    else
      blk[i, 2] := (x0 + x4) shr 8;
    if x8 + x6 < 0 then
      blk[i, 3] := ((x8 + x6) shr 8) or ((not Integer(0)) shl (32 - 8))
    else
      blk[i, 3] := (x8 + x6) shr 8;
    if x8 - x6 < 0 then
      blk[i, 4] := ((x8 - x6) shr 8) or ((not Integer(0)) shl (32 - 8))
    else
      blk[i, 4] := (x8 - x6) shr 8;
    if x0 - x4 < 0 then
      blk[i, 5] := ((x0 - x4) shr 8) or ((not Integer(0)) shl (32 - 8))
    else
      blk[i, 5] := (x0 - x4) shr 8;
    if x3 - x2 < 0 then
      blk[i, 6] := ((x3 - x2) shr 8) or ((not Integer(0)) shl (32 - 8))
    else
      blk[i, 6] := (x3 - x2) shr 8;
    if x7 - x1 < 0 then
      blk[i, 7] := ((x7 - x1) shr 8) or ((not Integer(0)) shl (32 - 8))
    else
      blk[i, 7] := (x7 - x1) shr 8;
  end;
end;
//////////////////////////////////////////////////////////////////////////////


procedure idctcol(var blk: MyInt);
var
  j, x0, x1, x2, x3, x4, x5, x6, x7, x8: Integer;
  Temp: Integer;
begin
  //intcut
  for j := 0 to 7 do
  begin
    x1 := blk[4, j] shl 8;
    x2 := blk[6, j];
    x3 := blk[2, j];
    x4 := blk[1, j];
    x5 := blk[7, j];
    x6 := blk[5, j];
    x7 := blk[3, j];
    if ((x1 or x2 or x3 or x4 or x5 or x6 or x7) = 0) then
    begin
      if (blk[0, j] + 32) < 0 then
        Temp := ((blk[0, j] + 32) shr 6) or
          (not (Integer(0)) shl (32 - 6))
      else
        Temp := (blk[0, j] + 32) shr 6;
      blk[1, j] := iclip[512 + Temp];
      blk[2, j] := iclip[512 + Temp];
      blk[3, j] := iclip[512 + Temp];
      blk[4, j] := iclip[512 + Temp];
      blk[5, j] := iclip[512 + Temp];
      blk[6, j] := iclip[512 + Temp];
      blk[7, j] := iclip[512 + Temp];
      blk[0, j] := iclip[512 + Temp];
      Continue;
    end;
    x0 := (blk[0, j] shl 8) + 8192;
    //first stage
    x8 := W7 * (x4 + x5) + 4;
    if (x8 + (W1 - W7) * x4) < 0 then
      x4 := ((x8 + (W1 - W7) * x4) shr 3) or
        (not (Integer(0)) shl (32 - 3))
    else
      x4 := (x8 + (W1 - W7) * x4) shr 3;
    if (x8 - (W1 + W7) * x5) < 0 then
      x5 := ((x8 - (W1 + W7) * x5) shr 3) or
        (not (Integer(0)) shl (32 - 3))
    else
      x5 := (x8 - (W1 + W7) * x5) shr 3;
    x8 := W3 * (x6 + x7) + 4;
    if (x8 - (W3 - W5) * x6) < 0 then
      x6 := ((x8 - (W3 - W5) * x6) shr 3) or
        (not (Integer(0)) shl (32 - 3))
    else
      x6 := (x8 - (W3 - W5) * x6) shr 3;
    if (x8 - (W3 + W5) * x7) < 0 then
      x7 := ((x8 - (W3 + W5) * x7) shr 3) or
        (not (Integer(0)) shl (32 - 3))
    else
      x7 := (x8 - (W3 + W5) * x7) shr 3;
    //second stage
    x8 := x0 + x1;
    x0 := x0 - x1;
    x1 := W6 * (x3 + x2) + 4;
    if (x1 - (W2 + W6) * x2) < 0 then
      x2 := ((x1 - (W2 + W6) * x2) shr 3) or
        (not (Integer(0)) shl (32 - 3))
    else
      x2 := (x1 - (W2 + W6) * x2) shr 3;
    if (x1 + (W2 - W6) * x3) < 0 then
      x3 := ((x1 + (W2 - W6) * x3) shr 3) or
        (not (Integer(0)) shl (32 - 3))
    else
      x3 := (x1 + (W2 - W6) * x3) shr 3;
    x1 := x4 + x6;
    x4 := x4 - x6;
    x6 := x5 + x7;
    x5 := x5 - x7;
    //third stage
    x7 := x8 + x3;
    x8 := x8 - x3;
    x3 := x0 + x2;
    x0 := x0 - x2;
    if (181 * (x4 + x5) + 128) < 0 then
      x2 := ((181 * (x4 + x5) + 128) shr 8) or
        (not (Integer(0)) shl (32 - 8))
    else
      x2 := (181 * (x4 + x5) + 128) shr 8;
    if (181 * (x4 - x5) + 128) < 0 then
      x4 := ((181 * (x4 - x5) + 128) shr 8) or
        (not (Integer(0)) shl (32 - 8))
    else
      x4 := (181 * (x4 - x5) + 128) shr 8;
    //fourth stage
    if x7 + x1 < 0 then
      Temp := ((x7 + x1) shr 14) or (not (Integer(0)) shl (32 - 14))
    else
      Temp := (x7 + x1) shr 14;
    blk[0, j] := iclip[512 + Temp];
    if x3 + x2 < 0 then
      Temp := ((x3 + x2) shr 14) or (not (Integer(0)) shl (32 - 14))
    else
      Temp := (x3 + x2) shr 14;
    blk[1, j] := iclip[512 + Temp];
    if x0 + x4 < 0 then
      Temp := ((x0 + x4) shr 14) or (not (Integer(0)) shl (32 - 14))
    else
      Temp := (x0 + x4) shr 14;
    blk[2, j] := iclip[512 + Temp];
    if x8 + x6 < 0 then
      Temp := ((x8 + x6) shr 14) or (not (Integer(0)) shl (32 - 14))
    else
      Temp := (x8 + x6) shr 14;
    blk[3, j] := iclip[512 + Temp];
    if x8 - x6 < 0 then
      Temp := ((x8 - x6) shr 14) or (not (Integer(0)) shl (32 - 14))
    else
      Temp := (x8 - x6) shr 14;
    blk[4, j] := iclip[512 + Temp];
    if x0 - x4 < 0 then
      Temp := ((x0 - x4) shr 14) or (not (Integer(0)) shl (32 - 14))
    else
      Temp := (x0 - x4) shr 14;
    blk[5, j] := iclip[512 + Temp];
    if x3 - x2 < 0 then
      Temp := ((x3 - x2) shr 14) or (not (Integer(0)) shl (32 - 14))
    else
      Temp := (x3 - x2) shr 14;
    blk[6, j] := iclip[512 + Temp];
    if x7 - x1 < 0 then
      Temp := ((x7 - x1) shr 14) or (not (Integer(0)) shl (32 - 14))
    else
      Temp := (x7 - x1) shr 14;
    blk[7, j] := iclip[512 + Temp];
  end;
end;


end.

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户1473556 2008-12-20 16:00

不错,初学者很好的资料。楼主能不能把JPEG的详细解码过程讲解一遍?谢谢
相关推荐阅读
用户147800 2010-12-22 10:59
microblaze lmb bram
entity lmb_v10 is generic ( C_LMB_NUM_SLAVES : integer := 4; C_LMB_DWIDTH : integer :...
用户147800 2010-12-22 08:55
microblaze SDRAM
BEGIN mpmc PARAMETER INSTANCE = mpmc_0 PARAMETER HW_VER = 5.00.a PARAMETER C_MEM_PARTNO = MT48LC32M1...
用户147800 2010-08-16 16:18
自己归纳整理的ARM THUMB指令机器码表
http://download.ednchina.com/Detail/121141/资料名称:自己归纳整理的ARM THUMB指令机器码表整理日期:2010/4/23详细介绍:        有个项...
用户147800 2010-08-03 19:30
FPGA logic analyzer
http://www.saleae.com/logic/etail. Lots of it.Store up to 500M samples at speeds as fast as 24MB/s.U...
用户147800 2010-07-21 16:06
跟我写ARM处理器之一:从写module arm( 开始
http://free-arm.blog.163.com/blog/static/1076779632009497742348/跟我写ARM处理器之一:从写module arm( 开始  我决定把我写...
用户147800 2010-07-17 22:39
FPGA Based Logic Analyzer
FPGA Based Logic AnalyzerThe outcome of this project is a logic analysator for home use.The project ...
我要评论
1
5
关闭 站长推荐上一条 /3 下一条