我该怎么用这个过程啊?

sdenf 2004-11-11 11:05:04
我在网上找到了这个,但我不知道我该怎么用啊?
该怎么引入一段数据流让它解压出来呢?解压以后的数据我怎么得到呢?
求大侠救救命,我DELPHI是赶鸭子上架啊
const // LZW encoding and decoding support
NoLZWCode = 4096;

type
PByte = ^Byte;

TByteStream = array[0..MaxInt - 1] of Byte;
PByteStream = ^TByteStream;

// abstract decoder class to define the base functionality of an encoder/decoder
TDecoder = class
public
procedure Decode(var Source: Pointer; Dest: Pointer; PackedSize, UnpackedSize: Integer); virtual; abstract;
procedure Encode(Source, Dest: Pointer; var FByteCounts: Cardinal); virtual; abstract;
end;

// Note: We need a different LZW decoder class for GIF because the bit order is reversed compared to that
// of TIFF and the code size increment is handled slightly different.
TGIFLZW = class(TDecoder)
private
FCodeSize: Cardinal;
FCodeMask: Cardinal;
FFreeCode: Cardinal;
FOldCode: Cardinal;
FPrefix: array[0..4095] of Cardinal; // LZW prefix
FSuffix, // LZW suffix
FStack: array [0..4095] of Byte; // stack
FStackPointer: PByte;
FTarget: PByte;
FFirstChar: Byte; // buffer for decoded byte
FClearCode,
FEOICode: Word;
function DecodeLZW(Code: Cardinal): Boolean;
public
InitialCodeSize: Byte; // must be set before decoding is started!
procedure Decode(var Source: Pointer; Dest: Pointer; PackedSize, UnpackedSize: Integer); override;
procedure Encode(Source, Dest: Pointer; var FByteCounts: Cardinal); override;
end;

implementation


function TGIFLZW.DecodeLZW(Code: Cardinal): Boolean;

var
InCode: Cardinal; // buffer for passed code

begin
// handling of clear codes
if Code = FClearCode then
begin
// reset of all variables
FCodeSize := InitialCodeSize + 1;
FCodeMask := (1 shl FCodeSize) - 1;
FFreeCode := FClearCode + 2;
FOldCode := NoLZWCode;
Result := True;
Exit;
end;

// check whether it is a valid, already registered code
if Code > FFreeCode then
raise Exception.Create('GIF LZW: invalid opcode.');

// handling for the first LZW code: print and keep it
if FOldCode = NoLZWCode then
begin
FFirstChar := FSuffix[Code];
FTarget^ := FFirstChar;
Inc(FTarget);
FOldCode := Code;
Result := True;
Exit;
end;

// keep the passed LZW code
InCode := Code;

// the first LZW code is always smaller than FFirstCode
if Code = FFreeCode then
begin
FStackPointer^ := FFirstChar;
Inc(FStackPointer);
Code := FOldCode;
end;

// loop to put decoded bytes onto the stack
while Code > FClearCode do
begin
FStackPointer^ := FSuffix[Code];
Inc(FStackPointer);
Code := FPrefix[Code];
end;

// place new code into code table
FFirstChar := FSuffix[Code];
FStackPointer^ := FFirstChar;
Inc(FStackPointer);
FPrefix[FFreeCode] := FOldCode;
FSuffix[FFreeCode] := FFirstChar;

// increase code size if necessary
if (FFreeCode = FCodeMask) and
(FCodeSize < 12) then
begin
Inc(FCodeSize);
FCodeMask := (1 shl FCodeSize) - 1;
end;
if FFreeCode < 4095 then Inc(FFreeCode);

// put decoded bytes (from the stack) into the target buffer
FOldCode := InCode;
repeat
Dec(FStackPointer);
FTarget^ := FStackPointer^;
Inc(FTarget);
until FStackPointer = @FStack;

Result := True;
end;

//----------------------------------------------------------------------------------------------------------------------

procedure TGIFLZW.Decode(var Source: Pointer; Dest: Pointer; PackedSize, UnpackedSize: Integer);

var
I: Integer;
Data, // current data
Bits, // counter for bit management
Code: Cardinal; // current code value
SourcePtr: PByte;

begin
FTarget := Dest;
SourcePtr := Source;

// initialize parameter
FCodeSize := InitialCodeSize + 1;
FClearCode := 1 shl InitialCodeSize;
FEOICode := FClearCode + 1;
FFreeCode := FClearCode + 2;
FOldCode := NoLZWCode;
FCodeMask := (1 shl FCodeSize) - 1;

// init code table
for I := 0 to FClearCode - 1 do
begin
FPrefix[I] := NoLZWCode;
FSuffix[I] := I;
end;

// initialize stack
FStackPointer := @FStack;

Data := 0;
Bits := 0;
while PackedSize > 0 do
begin
// read code from bit stream
Inc(Data, SourcePtr^ shl Bits);
Inc(Bits, 8);
while Bits >= FCodeSize do
begin
// current code
Code := Data and FCodeMask;
// prepare next run
Data := Data shr FCodeSize;
Dec(Bits, FCodeSize);

// EOICode -> decoding finished, check also for badly written codes and
// terminate the loop as soon as the target is filled up
if (Code = FEOICode) or
((PChar(FTarget) - PChar(Dest)) >= UnpackedSize) then Exit;

if not DecodeLZW(Code) then Break;
end;
Inc(SourcePtr);
Dec(PackedSize);
end;
end;
...全文
146 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
beyondtkl 2004-11-12
  • 打赏
  • 举报
回复
procedure Decode(var Source: Pointer; Dest: Pointer; PackedSize, UnpackedSize: Integer); override;
procedure Encode(Source, Dest: Pointer; var FByteCounts: Cardinal); override;

var
Source: array[0..1000] of char;
Dest: array[0..1000] of char;
pSource: Pointer;
pDest: Pointer;
btCounts: Cardinal;

pSource := (Pointer)@Source;
pDest := (Pointer)@Dest;
Decode(pSource, pDest, 100, 100); 后面的参数看你传了。。

Encode(pSouce, pDest, btCounts);

just try it.
sdenf 2004-11-12
  • 打赏
  • 举报
回复
没成功啊,哪位大哥大姐给个实例啊,行行好吧
sdenf 2004-11-12
  • 打赏
  • 举报
回复
我试过了,不行,大哥,你能给试试是哪儿的问题吗?

beyondtkl(大龙驹<弱水三K, 我取1bit>),太谢谢你啦,大恩人纳
beyondtkl 2004-11-12
  • 打赏
  • 举报
回复
你source ,dest都声明为 BYTE型数组看看。。

实在不行 我有空给你测试一下。
sdenf 2004-11-12
  • 打赏
  • 举报
回复
通过去了
但是,我给Source赋值,我查看了运行后的Dest没有得到正确的数据啊
beyondtkl 2004-11-12
  • 打赏
  • 举报
回复
:-( 不好意思 写错了那是C++的类型转换写法。。唉

要这样
pSource := Pointer(@Source);
pDest := Pointer(@Dest);

Decode(pSource, pDest, 100, 100);它说没有Decode?
你上面不是有的么。。。你use 这个unit没。。。
sdenf 2004-11-12
  • 打赏
  • 举报
回复
beyondtkl(大龙驹<弱水三K, 我取1bit>) :
你的方法怎么有很多错误呢?
pSource := (Pointer)@Source; 它说这样不行?
Decode(pSource, pDest, 100, 100);它说没有Decode?
sdenf 2004-11-12
  • 打赏
  • 举报
回复
我查着帮助,这样写的,但是异常出错啊,怎么办呢?
var
ms,mt : TMemoryStream;
i : Integer;
P1,P2: Pointer;
Myclass:TGIFLZW;
begin
ms:= TMemoryStream.Create;
mt:= TMemoryStream.Create;
mt.SetSize(5078);
ms.LoadFromFile('5.gif');
P1:= Pchar(ms);
P2:=PChar(mt);
MyClass := TGIFLZW.Create;
MyClass.Decode(P1,P2,8,256);
MyClass.Destroy;
ms.Free;
mt.free;
end
sdenf 2004-11-11
  • 打赏
  • 举报
回复
Source: Pointer; Dest: Pointer这两个指针怎么办,应该建立一个什么样的文件,然后怎么指向它呢?
ICMGDCHN 2004-11-11
  • 打赏
  • 举报
回复
procedure Decode(var Source: Pointer; Dest: Pointer; PackedSize, UnpackedSize: Integer); override;
procedure Encode(Source, Dest: Pointer; var FByteCounts: Cardinal); override;

看到里面的VAR参数没?返回值就在那里.
sdenf 2004-11-11
  • 打赏
  • 举报
回复
这个大家不必看明白,只要大家说清楚点怎么调用,怎么输出数据有好了

jinjazz(近身剪(N-P攻略)大哥,请详细解释,好吗?
surpassable 2004-11-11
  • 打赏
  • 举报
回复
long ~~~~~~
jinjazz 2004-11-11
  • 打赏
  • 举报
回复
create

调用成员函数

free
hellolongbin 2004-11-11
  • 打赏
  • 举报
回复
果然,真的很长
beyondtkl 2004-11-11
  • 打赏
  • 举报
回复
:-) 有点长。
hottey 2004-11-11
  • 打赏
  • 举报
回复
好长好长,好长好长!
sdenf 2004-11-11
  • 打赏
  • 举报
回复
谢谢, ICMGDCHN(广东人在广州-->喜欢明月)大哥,明天事试再说
ICMGDCHN 2004-11-11
  • 打赏
  • 举报
回复
var
Source:pchar;//字符指针;
Dest:pchar;

Source:pInteger;
Dest:pInteger;
看下你的数据类型定义吧,然后开辟缓冲区存贮你的数据,用指针指向该缓冲区.

具体的我没仔细读你的程序,大概思路就是这样
sdenf 2004-11-11
  • 打赏
  • 举报
回复
555~~

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧