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

📄 jpegdecode.pas

📁 用于jpeg文件解码的delphi源代码
💻 PAS
📖 第 1 页 / 共 3 页
字号:
		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[i]:=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[i]:=0;
		QtZzMCUBuffer[i]:=0;
	end;
	for i:=0 to 63 do
        begin
		Y[i]:=0;
		U[i]:=0;
		V[i]:=0;
		BlockBuffer[i]:=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[i]:=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];

⌨️ 快捷键说明

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