实例介绍
【实例简介】
【实例截图】
【实例截图】
【核心代码】
unit Lzw; // Lzw.LZWBUFFER
interface
uses
Windows, SysUtils, Classes;
const
NOCODE = -1; // 空编码
LZWBITS = 8; // 字对处理位
LZWBUFFER = $FFFF; // 64KB 编码处理缓存容量(输入缓存容量。经实践,该值能达到较好的效率 )
LZWMAXBITS = 12; // 最大的编码位(增加该值会增加编码表的内存空间)
LZWSTACKBUFFERSIZE = $FFFF; // 64KB 栈缓存容量(要保证它足够大)
LZWEXPORTBLOCKSIZE = $FFFF; // 64KB 输出缓存容量
LZWMAXCODES = 1 shl LZWMAXBITS; // 最大编码(4096)
LZWTABLESIZE = 1 shl ( LZWBITS LZWMAXBITS ); // 编码表容量(2MB空间)
type
TagArrayByteType = array of Byte;
pTagArrayByteType = ^TagArrayByteType;
// Data: array of Byte;
// end;
TLZWEncode = class( TObject )
private
EncodeTable: array [ 0 .. LZWTABLESIZE - 1 ] of Word; // 编码表
EncodePointer: array [ 0 .. LZWMAXCODES - 1 ] of LongWord; // 经过编码的缓存
ExportBlock: Pointer; // 存放编码后的数据指针(输出缓存块指针)
ExportBlockPtr: array of Byte; // 该指针指向 ExportBlock ,用于访问数组
InitBits: Integer; // 压缩数据的起始位数
ClearCode: Integer; // 清除码
EofCode: Integer; // 结束码
PrefixCode: Integer; // 字头码
SuffixCode: Integer; // 字尾码
Encode: Integer; // 压缩编码
RunBits: Integer; // 当前处理位
MaxCodeSize: Integer; // 当前处理最大编码
FBegin: Boolean; // 开始处理标志
FExportSize: Integer; // 输出数据块大小
FExportIndex: Integer; // 输出数据块索引
FExportTotalSize: Integer; // 记录输出缓存块大小
ShiftBits: Integer; // 用于位处理,作临时位
ShiftCode: Integer; // 用于位处理,作临时代码
protected
procedure ExportData( AData: Integer ); virtual; // 输出数据(虚方法)
public
function GetExportPointer: Pointer; // 返回输出指针
function GetExportSize: Integer; // 返回输出大小
procedure GetBegin; // 置开始编码标志
procedure GetEnd; // 置结束编码标志
procedure Execute( Data: array of Byte; DataSize: Integer ); virtual; // 执行编码过程(虚方法virtual)
procedure ExecutePointer( pData: Pointer; DataSize: Integer ); virtual; // 执行编码过程(虚方法)
// procedure ExecutepData(Data: pTagArrayByteType; DataSize: Integer); virtual; // 执行编码过程(虚方法)
constructor Create;
destructor Destroy; override;
end;
TLZWUnencode = class( TObject )
private
InitBits: Integer; // 压缩数据的起始位数
ClearCode: Integer; // 清除码
EofCode: Integer; // 结束码
PrefixCode: Integer; // 字头码
SuffixCode: Integer; // 字尾码
Encode: Integer; // 压缩编码
RunBits: Integer; // 当前处理位
MaxCodeSize: Integer; // 当前处理最大编码
ExportBlock: Pointer; // 存放编码后的数据指针(输出缓存块指针)
ExportBlockPtr: array of Byte; // 该指针指向 ExportBlock ,用于访问数组
StackIndex: Integer; // 栈索引
StackTable: array [ 0 .. LZWSTACKBUFFERSIZE - 1 ] of Byte; // 栈表
PrefixTable: array [ 0 .. LZWMAXCODES - 1 ] of Word; // 字头表
SuffixTable: array [ 0 .. LZWMAXCODES - 1 ] of Byte; // 字尾表
FExportSize: Integer; // 输出数据块大小
FExportIndex: Integer; // 输出数据块索引
FExportTotalSize: Integer; // 记录输出缓存块大小
ShiftBits: Integer; // 用于位处理,作临时位
ShiftCode: Integer; // 用于位处理,作临时代码
protected
procedure ExportData( AData: Integer ); virtual; // 输出数据(虚方法)
public
function GetExportPointer: Pointer; // 返回输出指针
function GetExportSize: Integer; // 返回输出大小
procedure GetBegin; // 开始解码(分配输出内存空间)
procedure GetEnd; // 结束解码(释放输出内存空间)
procedure Execute( Data: array of Byte; DataSize: Integer ); virtual; // 执行解码过程(虚方法)
procedure ExecutePointer( pData: Pointer; DataSize: Integer ); virtual; // 执行解码过程(虚方法)
constructor Create;
destructor Destroy; override;
end;
implementation
{ TLZWEncode }
constructor TLZWEncode.Create;
begin
InitBits := LZWBITS;
ClearCode := 1 shl InitBits;
EofCode := ClearCode 1;
Encode := EofCode 1;
RunBits := InitBits 1;
MaxCodeSize := 1 shl RunBits;
FBegin := False;
FExportSize := 0;
FExportIndex := 0;
FExportTotalSize := 0;
ShiftBits := 0;
ShiftCode := 0;
end;
destructor TLZWEncode.Destroy;
begin
FreeMem( ExportBlock );
inherited;
end;
procedure TLZWEncode.ExecutePointer( pData: Pointer; DataSize: Integer ); // 执行编码过程(虚方法)
// procedure TLZWEncode.ExecutePchar(pData:Pchar ; DataSize: Integer);
var
AIndex: Integer;
ArrayIndex: Integer;
Vi: Integer;
// Data : TagArrayByteType;
pByteV: pByte;
begin
AIndex := 0;
FExportIndex := 0;
FExportTotalSize := LZWEXPORTBLOCKSIZE;
// 处理文件首字节,赋值给字头码/
// Data := pData;
pByteV := pByte( pData );
if FBegin then
begin
FBegin := False;
ExportData( ClearCode );
// PrefixCode := Data[AIndex];
PrefixCode := pByteV^;
// PrefixCode := Byte(pByteV^);
Inc( AIndex );
Inc( pByteV );
end;
// 编码过程/
while AIndex < DataSize do
begin
// 取出数据,赋值给字尾码 /
// SuffixCode := Data[AIndex];
SuffixCode := Integer( pByteV^ );
Inc( pByteV );
Inc( AIndex );
// 构造地址/
ArrayIndex := ( PrefixCode shl LZWBITS ) SuffixCode;
// 无可编码字对的情况/
if EncodeTable[ ArrayIndex ] = 0 then
begin
ExportData( PrefixCode ); // 输出字头
// 当前编码等于最大编码值的情况,作初始化工作//
if Encode = LZWMAXCODES then
begin
ExportData( ClearCode ); // 输出清除码
Encode := EofCode 1;
RunBits := InitBits 1;
MaxCodeSize := 1 shl RunBits;
// 只需初始化编码过的内存区 /
for Vi := Encode to LZWMAXCODES - 1 do
EncodeTable[ EncodePointer[ Vi ] ] := 0;
end
else
begin
// 当前编码等于最大处理编码的情况 /
if Encode = MaxCodeSize then
begin
Inc( RunBits ); // 当前处理位增加
MaxCodeSize := 1 shl RunBits; // 相应最大编码增加
end;
EncodeTable[ ArrayIndex ] := Encode; // 加入编码表
EncodePointer[ Encode ] := ArrayIndex;
Inc( Encode );
end;
PrefixCode := SuffixCode;
end
// 编码可匹配的情况 /
else
begin
PrefixCode := EncodeTable[ ArrayIndex ];
end;
end;
end;
procedure TLZWEncode.Execute( Data: array of Byte; DataSize: Integer );
var
AIndex: Integer;
ArrayIndex: Integer;
Vi: Integer;
begin
AIndex := 0;
FExportIndex := 0;
FExportTotalSize := LZWEXPORTBLOCKSIZE;
{ 处理文件首字节,赋值给字头码 }
if FBegin then
begin
FBegin := False;
ExportData( ClearCode );
PrefixCode := Data[ AIndex ];
Inc( AIndex );
end;
{ 编码过程 }
while AIndex < DataSize do
begin
{ 取出数据,赋值给字尾码 }
SuffixCode := Data[ AIndex ];
Inc( AIndex );
{ 构造地址 }
ArrayIndex := ( PrefixCode shl LZWBITS ) SuffixCode;
{ 无可编码字对的情况 }
if EncodeTable[ ArrayIndex ] = 0 then
begin
ExportData( PrefixCode ); // 输出字头
{ 当前编码等于最大编码值的情况,作初始化工作 }
if Encode = LZWMAXCODES then
begin
ExportData( ClearCode ); // 输出清除码
Encode := EofCode 1;
RunBits := InitBits 1;
MaxCodeSize := 1 shl RunBits;
{ 只需初始化编码过的内存区 }
for Vi := Encode to LZWMAXCODES - 1 do
EncodeTable[ EncodePointer[ Vi ] ] := 0;
end
else
begin
{ 当前编码等于最大处理编码的情况 }
if Encode = MaxCodeSize then
begin
Inc( RunBits ); // 当前处理位增加
MaxCodeSize := 1 shl RunBits; // 相应最大编码增加
end;
EncodeTable[ ArrayIndex ] := Encode; // 加入编码表
EncodePointer[ Encode ] := ArrayIndex;
Inc( Encode );
end;
PrefixCode := SuffixCode;
end
{ 编码可匹配的情况 }
else
begin
PrefixCode := EncodeTable[ ArrayIndex ];
end;
end;
end;
procedure TLZWEncode.ExportData( AData: Integer );
{ 输出过程 }
procedure ExportProcedure;
begin
while ShiftBits >= LZWBITS do
begin
ExportBlockPtr[ FExportIndex ] := ShiftCode and $00FF;
Inc( FExportIndex );
if FExportIndex = FExportTotalSize then
begin
{ 重新分配内存后首地址可能改变 }
ReallocMem( ExportBlock, FExportIndex LZWEXPORTBLOCKSIZE );
Pointer( ExportBlockPtr ) := ExportBlock;
Inc( FExportTotalSize, LZWEXPORTBLOCKSIZE );
end;
ShiftCode := ShiftCode shr LZWBITS;
Dec( ShiftBits, LZWBITS );
end;
end;
begin
{ 输出位总是大于 LZWBITS 的 }
ShiftCode := AData shl ShiftBits ShiftCode;
Inc( ShiftBits, RunBits );
ExportProcedure;
end;
function TLZWEncode.GetExportPointer: Pointer;
begin
Result := ExportBlock;
end;
function TLZWEncode.GetExportSize: Integer;
begin
FExportSize := FExportIndex;
Result := FExportSize;
end;
procedure TLZWEncode.GetBegin;
begin
{
InitBits := LZWBITS;
ClearCode := 1 shl InitBits;
EofCode := ClearCode 1;
Encode := EofCode 1;
RunBits := InitBits 1;
MaxCodeSize := 1 shl RunBits;
FBegin := False;
FExportSize := 0;
FExportIndex := 0;
FExportTotalSize := 0;
ShiftBits := 0;
ShiftCode := 0;
}
FBegin := True;
{ 有可能输出缓存大于输入缓存,如果发生,到时再重新分配内存 }
ExportBlock := AllocMem( LZWEXPORTBLOCKSIZE );
Pointer( ExportBlockPtr ) := ExportBlock;
end;
procedure TLZWEncode.GetEnd;
begin
ExportData( PrefixCode );
ExportData( EofCode );
{ 最后的处理是看看有没有 , 没处理的位 }
while ShiftBits > 0 do
begin
ExportBlockPtr[ FExportIndex ] := ShiftCode and $00FF;
Inc( FExportIndex );
if FExportIndex = FExportTotalSize then
begin
ReallocMem( ExportBlock, FExportIndex LZWEXPORTBLOCKSIZE );
Pointer( ExportBlockPtr ) := ExportBlock;
Inc( FExportTotalSize, LZWEXPORTBLOCKSIZE );
end;
ShiftCode := ShiftCode shr LZWBITS;
Dec( ShiftBits, LZWBITS );
end;
end;
{ TLZWUnencode }
constructor TLZWUnencode.Create;
begin
InitBits := LZWBITS;
ClearCode := 1 shl InitBits;
EofCode := ClearCode 1;
Encode := EofCode 1;
RunBits := InitBits 1;
MaxCodeSize := 1 shl RunBits;
ShiftBits := 0;
ShiftCode := 0;
FExportSize := 0;
FExportIndex := 0;
FExportTotalSize := 0;
end;
destructor TLZWUnencode.Destroy;
begin
inherited;
end;
// sss
procedure TLZWUnencode.ExecutePointer( pData: Pointer; DataSize: Integer );
const
MaskCode: array [ 0 .. LZWMAXBITS ] of Word = ( $0000, $0001, $0003, $0007, $000F, $001F, $003F, $007F, $00FF, $01FF, $03FF,
$07FF, $0FFF );
var
AIndex: Integer;
CurrentCode, ACode: Integer;
pByteBuf: pByte;
begin
pByteBuf := pData;
AIndex := 0;
FExportIndex := 0;
FExportTotalSize := LZWSTACKBUFFERSIZE;
{ 解码过程 }
while AIndex < DataSize do
begin
// PByteBuf := LongWord(pData AIndex);
{ 取出数据 }
while ( ShiftBits < RunBits ) and ( AIndex < DataSize ) do
begin
// ShiftCode := Data[AIndex] shl ShiftBits ShiftCode;
ShiftCode := pByteBuf^ shl ShiftBits ShiftCode;
Inc( AIndex );
Inc( pByteBuf );
Inc( ShiftBits, LZWBITS );
end;
if AIndex >= DataSize then
Exit;
CurrentCode := ShiftCode and MaskCode[ RunBits ];
ShiftCode := ShiftCode shr RunBits;
Dec( ShiftBits, RunBits );
{ 遇到结束码则退出 }
if CurrentCode = EofCode then
Exit;
{ 遇到清除码则初始化 }
if CurrentCode = ClearCode then
begin
RunBits := InitBits 1;
Encode := EofCode 1;
MaxCodeSize := 1 shl RunBits;
PrefixCode := NOCODE;
SuffixCode := NOCODE;
end
else
begin
ACode := CurrentCode;
StackIndex := 0;
{ 当前代码正好与当前编码值相等的情况 }
if ACode = Encode then
begin
StackTable[ StackIndex ] := SuffixCode;
Inc( StackIndex );
ACode := PrefixCode;
end;
{ 当前代码大于当前编码值的情况,递归取值 }
while ACode > EofCode do
begin
StackTable[ StackIndex ] := SuffixTable[ ACode ];
Inc( StackIndex );
ACode := PrefixTable[ ACode ];
end;
SuffixCode := ACode;
{ 输出数据 }
ExportData( ACode );
while StackIndex > 0 do
begin
Dec( StackIndex );
ExportData( StackTable[ StackIndex ] );
end;
{ 加入字典 }
if ( Encode < LZWMAXCODES ) and ( PrefixCode <> NOCODE ) then
begin
PrefixTable[ Encode ] := PrefixCode;
SuffixTable[ Encode ] := SuffixCode;
Inc( Encode );
if ( Encode >= MaxCodeSize ) and ( RunBits < LZWMAXBITS ) then
begin
MaxCodeSize := MaxCodeSize shl 1;
Inc( RunBits );
end;
end;
PrefixCode := CurrentCode;
end;
end;
end;
procedure TLZWUnencode.Execute( Data: array of Byte; DataSize: Integer );
const
MaskCode: array [ 0 .. LZWMAXBITS ] of Word = ( $0000, $0001, $0003, $0007, $000F, $001F, $003F, $007F, $00FF, $01FF, $03FF,
$07FF, $0FFF );
var
AIndex: Integer;
CurrentCode, ACode: Integer;
begin
AIndex := 0;
FExportIndex := 0;
FExportTotalSize := LZWSTACKBUFFERSIZE;
{ 解码过程 }
while AIndex < DataSize do
begin
{ 取出数据 }
while ( ShiftBits < RunBits ) and ( AIndex < DataSize ) do
begin
ShiftCode := Data[ AIndex ] shl ShiftBits ShiftCode;
Inc( AIndex );
Inc( ShiftBits, LZWBITS );
end;
if AIndex >= DataSize then
Exit;
CurrentCode := ShiftCode and MaskCode[ RunBits ];
ShiftCode := ShiftCode shr RunBits;
Dec( ShiftBits, RunBits );
{ 遇到结束码则退出 }
if CurrentCode = EofCode then
Exit;
{ 遇到清除码则初始化 }
if CurrentCode = ClearCode then
begin
RunBits := InitBits 1;
Encode := EofCode 1;
MaxCodeSize := 1 shl RunBits;
PrefixCode := NOCODE;
SuffixCode := NOCODE;
end
else
begin
ACode := CurrentCode;
StackIndex := 0;
{ 当前代码正好与当前编码值相等的情况 }
if ACode = Encode then
begin
StackTable[ StackIndex ] := SuffixCode;
Inc( StackIndex );
ACode := PrefixCode;
end;
{ 当前代码大于当前编码值的情况,递归取值 }
while ACode > EofCode do
begin
StackTable[ StackIndex ] := SuffixTable[ ACode ];
Inc( StackIndex );
ACode := PrefixTable[ ACode ];
end;
SuffixCode := ACode;
{ 输出数据 }
ExportData( ACode );
while StackIndex > 0 do
begin
Dec( StackIndex );
ExportData( StackTable[ StackIndex ] );
end;
{ 加入字典 }
if ( Encode < LZWMAXCODES ) and ( PrefixCode <> NOCODE ) then
begin
PrefixTable[ Encode ] := PrefixCode;
SuffixTable[ Encode ] := SuffixCode;
Inc( Encode );
if ( Encode >= MaxCodeSize ) and ( RunBits < LZWMAXBITS ) then
begin
MaxCodeSize := MaxCodeSize shl 1;
Inc( RunBits );
end;
end;
PrefixCode := CurrentCode;
end;
end;
end;
procedure TLZWUnencode.ExportData( AData: Integer );
begin
ExportBlockPtr[ FExportIndex ] := AData;
Inc( FExportIndex );
if FExportIndex = FExportTotalSize then
begin
ReallocMem( ExportBlock, FExportIndex LZWSTACKBUFFERSIZE );
Pointer( ExportBlockPtr ) := ExportBlock;
Inc( FExportTotalSize, LZWSTACKBUFFERSIZE );
end;
end;
procedure TLZWUnencode.GetBegin;
begin
ExportBlock := AllocMem( LZWSTACKBUFFERSIZE );
Pointer( ExportBlockPtr ) := ExportBlock;
end;
procedure TLZWUnencode.GetEnd;
begin
FreeMem( ExportBlock );
end;
function TLZWUnencode.GetExportPointer: Pointer;
begin
Result := ExportBlock;
end;
function TLZWUnencode.GetExportSize: Integer;
begin
FExportSize := FExportIndex;
Result := FExportSize;
end;
end.
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论