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

📄 sxpngutils.pas

📁 skin components for design of your applicastions
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  if Assigned(ChunkClasses) then
    for i:=0 to ChunkClasses.Count-1 do
    begin
      if pChunkClassInfo(ChunkClasses.Item[i])^.ClassName.GetName=Name then
      begin
        NewChunk:=pChunkClassInfo(ChunkClasses.Item[i])^.ClassName;
        break;
      end;
    end;
  Result:=NewChunk.Create(Owner);
  Result.fName:=Name;
end;

const ZLIBAllocate=High(Word);

function ZLIBInitInflate(Stream:TStream):TZStreamRec2;
begin
 FillChar(Result,sizeof(TZStreamRec2),#0);
 with Result do
  begin
    GetMem(Data,ZLIBAllocate);
    fStream:=Stream;
  end;
 InflateInit_(Result.zlib,zlib_version,sizeof(TZStreamRec));
end;

function ZLIBInitDeflate(Stream:TStream;
  Level:TCompressionlevel;Size:Cardinal):TZStreamRec2;
begin
  FillChar(Result,sizeof(TZStreamRec2),#0);
  with Result,ZLIB do
  begin
    GetMem(Data,Size);
    fStream:=Stream;
    next_out:=Data;
    avail_out:=Size;
  end;
  deflateInit_(Result.zlib,Level,zlib_version,sizeof(TZStreamRec));
end;

procedure ZLIBTerminateDeflate(var ZLIBStream:TZStreamRec2);
begin
  DeflateEnd(ZLIBStream.zlib);
  FreeMem(ZLIBStream.Data,ZLIBAllocate);
end;

procedure ZLIBTerminateInflate(var ZLIBStream:TZStreamRec2);
begin
  InflateEnd(ZLIBStream.zlib);
  FreeMem(ZLIBStream.Data,ZLIBAllocate);
end;

function DecompressZLIB(const Input:Pointer;InputSize:Integer;
  var Output:Pointer;var OutputSize:Integer;
  var ErrorOutput:String):Boolean;
var
  StreamRec:TZStreamRec;
  Buffer:array[Byte]of Byte;
  InflateRet:Integer;
begin
  with StreamRec do
  begin
    Result:=True;
    OutputSize:=0;
    FillChar(StreamRec,sizeof(TZStreamRec),#0);
    InflateInit_(StreamRec,zlib_version,sizeof(TZStreamRec));
    next_in:=Input;
    avail_in:=InputSize;
    repeat
      if (avail_out=0) then
      begin
        next_out:=@Buffer;
        avail_out:=sizeof(Buffer);
      end;
      InflateRet:=inflate(StreamRec,0);
      if (InflateRet=Z_STREAM_END) or (InflateRet=0) then
      begin
        Inc(OutputSize,total_out);
        if Output=nil then
          GetMem(Output,OutputSize) else ReallocMem(Output,OutputSize);
        CopyMemory(Ptr(Longint(Output)+OutputSize-total_out),
          @Buffer,total_out);
      end
      else if InflateRet<0 then
      begin
        Result:=False;
        ErrorOutput:=StreamRec.msg;
        InflateEnd(StreamRec);
        exit;
      end;
    until InflateRet=Z_STREAM_END;
    InflateEnd(StreamRec);
  end;
end;

function CompressZLIB(Input:Pointer;InputSize,CompressionLevel:Integer;
  var Output:Pointer;var OutputSize:Integer;
  var ErrorOutput:String):Boolean;
var
  StreamRec:TZStreamRec;
  Buffer:array[Byte]of Byte;
  DeflateRet:Integer;
begin
  with StreamRec do
  begin
    Result:=True;
    OutputSize:=0;
    FillChar(StreamRec,sizeof(TZStreamRec),#0);
    DeflateInit_(StreamRec,CompressionLevel,zlib_version,sizeof(TZStreamRec));
    next_in:=Input;
    avail_in:=InputSize;
    while avail_in>0 do
    begin
      if avail_out=0 then
      begin
        next_out:=@Buffer;
        avail_out:=sizeof(Buffer);
      end;
      DeflateRet:=deflate(StreamRec,Z_FINISH);
      if (DeflateRet=Z_STREAM_END) or (DeflateRet=0) then
      begin
        Inc(OutputSize,total_out);
        if Output=nil then
          GetMem(Output,OutputSize) else ReallocMem(Output,OutputSize);
        CopyMemory(Ptr(Longint(Output)+OutputSize-total_out),
          @Buffer,total_out);
      end
      else if DeflateRet<0 then
      begin
        Result:=False;
        ErrorOutput:=StreamRec.msg;
        DeflateEnd(StreamRec);
        exit;
      end;
    end;
    DeflateEnd(StreamRec);
  end;
end;

constructor TPNGPointerList.Create(AOwner:TPNGObject);
begin
 inherited Create;
 fOwner:=AOwner;
end;

function TPNGPointerList.Remove(Value:Pointer):Pointer;
var
  I,Position:Integer;
begin
  Position:=-1;
  for I:=0 to Count-1 do
    if Value=Item[I] then Position:=I;
  if Position>=0 then
  begin
    Result:=Item[Position];
    Dec(fCount);
    if Position<Integer(FCount) then
      System.Move(fMemory^[Position+1],fMemory^[Position],
      (Integer(fCount)-Position)*sizeof(Pointer));
  end else Result:=nil
end;

procedure TPNGPointerList.Add(Value:Pointer);
begin
  Count:=Count+1;
  Item[Count-1]:=Value;
end;

destructor TPNGPointerList.Destroy;
begin
 if fMemory<>nil then
  FreeMem(fMemory,fCount*sizeof(Pointer));
 inherited Destroy;
end;

function TPNGPointerList.GetItem(Index:Cardinal):Pointer;
begin
  if (Index<=Count-1) then
    Result:=fMemory[Index]
  else
    Result:=nil;
end;

procedure TPNGPointerList.Insert(Value:Pointer;Position:Cardinal);
begin
  if (Position<Count) then
  begin
    SetSize(Count+1);
    if Position<Count then
      System.Move(fMemory^[Position],fMemory^[Position+1],
        (Count-Position-1)*sizeof(Pointer));
    Item[Position]:=Value;
  end;
end;

procedure TPNGPointerList.SetItem(Index:Cardinal;const Value:Pointer);
begin
  if (Index<=Count-1) then
    fMemory[Index]:=Value
end;

procedure TPNGPointerList.SetSize(const Size:Cardinal);
begin
  if (fMemory=nil) and (Size>0) then
    GetMem(fMemory,Size*sizeof(Pointer))
  else
    if Size>0 then
      ReallocMem(fMemory,Size*sizeof(Pointer))
    else
    begin
      FreeMem(fMemory);
      fMemory:=nil;
    end;
  fCount:=Size;
end;

procedure TPNGList.RemoveChunk(Chunk:TChunk);
begin
  Remove(Chunk);
  Chunk.Free
end;

function TPNGList.Add(ChunkClass:TChunkClass):TChunk;
var
  IHDR:TChunkIHDR;
  IEND:TChunkIEND;

  IDAT:TChunkIDAT;
  PLTE:TChunkPLTE;
begin
  Result:=nil;
  if (ChunkClass=TChunkIHDR) or (ChunkClass=TChunkIDAT) or
    (ChunkClass=TChunkPLTE) or (ChunkClass=TChunkIEND) then
    fOwner.RaiseError(EPNGError,EPNGCannotAddChunkText)
  else if ((ChunkClass=TChunkgAMA) and (ItemFromClass(TChunkgAMA)<>nil)) or
     ((ChunkClass=TChunktRNS) and (ItemFromClass(TChunktRNS)<>nil)) then
    fOwner.RaiseError(EPNGError,EPNGCannotAddChunkText)
  else if (ItemFromClass(TChunkIEND)=nil) or
    (ItemFromClass(TChunkIHDR)=nil) then
    fOwner.RaiseError(EPNGError,EPNGCannotAddInvalidImageText)
  else
  begin
    IHDR:=ItemFromClass(TChunkIHDR) as TChunkIHDR;
    IEND:=ItemFromClass(TChunkIEND) as TChunkIEND;
    Result:=ChunkClass.Create(Owner);
    if (ChunkClass=TChunkgAMA) then
      Insert(Result,IHDR.Index+1)
    else if (ChunkClass=TChunktRNS) then
    begin
      IDAT:=ItemFromClass(TChunkIDAT) as TChunkIDAT;
      PLTE:=ItemFromClass(TChunkPLTE) as TChunkPLTE;
      if Assigned(PLTE) then
        Insert(Result,PLTE.Index+1)
      else if Assigned(IDAT) then
        Insert(Result,IDAT.Index)
      else
        Insert(Result,IHDR.Index+1)
    end
    else
      Insert(Result,IEND.Index);
  end;
end;

function TPNGList.GetItem(Index:Cardinal):TChunk;
begin
  Result:=inherited GetItem(Index);
end;

function TPNGList.ItemFromClass(ChunkClass:TChunkClass):TChunk;
var
  i:Integer;
begin
  Result:=nil;
  for i:=0 to Count-1 do
    if Item[i] is ChunkClass then
    begin
      Result:=Item[i];
      break;
    end;
end;

procedure TChunk.ResizeData(const NewSize:Cardinal);
begin
  fDataSize:=NewSize;
  ReallocMem(fData,NewSize+1);
end;

function TChunk.GetIndex:Integer;
var
  i:Integer;
begin
  Result:=-1;
  for i:=0 to Owner.Chunks.Count-1 do
    if Owner.Chunks.Item[i]=Self then
    begin
      Result:=i;
      exit;
    end;
end;

function TChunk.GetHeader:TChunkIHDR;
begin
  Result:=Owner.Chunks.Item[0] as TChunkIHDR;
end;

procedure TChunk.Assign(Source:TChunk);
begin
  fName:=Source.fName;
  ResizeData(Source.fDataSize);
  if fDataSize>0 then CopyMemory(fData,Source.fData,fDataSize);
end;

constructor TChunk.Create(Owner:TPNGObject);
var
  ChunkName:String;
begin
  inherited Create;
  ChunkName:=Copy(ClassName,Length('TChunk')+1,Length(ClassName));
  if Length(ChunkName)=4 then CopyMemory(@fName[0],@ChunkName[1],4);
  GetMem(fData,1);
  fDataSize:=0;
  fOwner:=Owner;
end;

destructor TChunk.Destroy;
begin
 FreeMem(fData,fDataSize+1);
 inherited Destroy;
end;

function TChunk.GetChunkName:String;
begin
  Result:=fName
end;

class function TChunk.GetName:String;
begin
  Result:=Copy(ClassName,Length('TChunk')+1,Length(ClassName));
end;

function TChunk.SaveData(Stream:TStream):Boolean;
var ChunkSize,ChunkCRC:Cardinal;
begin
  ChunkSize:=ByteSwap(DataSize);
  Stream.Write(ChunkSize,4);
  Stream.Write(fName,4);
  if DataSize>0 then Stream.Write(Data^,DataSize);
  ChunkCRC:=update_crc($ffffffff,@fName[0],4);
  ChunkCRC:=Byteswap(update_crc(ChunkCRC,Data,DataSize) xor $ffffffff);
  Stream.Write(ChunkCRC,4);
  Result:=True;
end;

function TChunk.SaveToStream(Stream:TStream):Boolean;
begin
  Result:=SaveData(Stream)
end;

function TChunk.LoadFromStream(Stream:TStream;const ChunkName:TChunkName;
  Size:Integer):Boolean;
var
  CheckCRC:Cardinal;
  RightCRC:Cardinal;
begin
  ResizeData(Size);
  if Size>0 then Stream.Read(fData^,Size);
  Stream.Read(CheckCRC,4);
  CheckCrc:=ByteSwap(CheckCRC);
  RightCRC:=update_crc($ffffffff,@ChunkName[0],4);
  RightCRC:=update_crc(RightCRC,fData,Size) xor $ffffffff;
  Result:=RightCRC=CheckCrc;
  if not Result then
   begin
    Owner.RaiseError(EPNGInvalidCRC,EPNGInvalidCRCText);
    exit;
   end;
end;

function TChunktIME.LoadFromStream(Stream:TStream;
  const ChunkName:TChunkName;Size:Integer):Boolean;
begin
  Result:=inherited LoadFromStream(Stream,ChunkName,Size);
  if not Result or (Size<>7) then exit;
  fYear:=((PByte(Longint(Data) )^)*256)+ (PByte(Longint(Data)+1)^);
  fMonth:=PByte(Longint(Data)+2)^;
  fDay:=PByte(Longint(Data)+3)^;
  fHour:=PByte(Longint(Data)+4)^;
  fMinute:=PByte(Longint(Data)+5)^;
  fSecond:=PByte(Longint(Data)+6)^;
end;

function TChunktIME.SaveToStream(Stream:TStream):Boolean;
begin
  ResizeData(7);
  PWord(Data)^:=Year;
  PByte(Longint(Data)+2)^:=Month;
  PByte(Longint(Data)+3)^:=Day;
  PByte(Longint(Data)+4)^:=Hour;
  PByte(Longint(Data)+5)^:=Minute;
  PByte(Longint(Data)+6)^:=Second;
  Result:=inherited SaveToStream(Stream);
end;

function TChunkzTXt.LoadFromStream(Stream:TStream;

⌨️ 快捷键说明

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