{ ������� ����������� �� ������ � ���� ������� pcx  }
{ ������� ����������� �� ����� ������� pcx �� ����� }

unit WorkPcx;

interface

procedure WriteFile( CenterX, CenterY, Scale: pointer );

function ReadFile( Name: string; CenterX, CenterY, Scale: pointer ): boolean;

implementation

uses Global;

type
  Header = record			{ ��������� pcx-����� }
    Manuf:	byte;
    Ver:	byte;
    Code:	byte;
    Bits:	byte;
    X1,Y1,X2,Y2:word;
    Hres:	word;
    VRes:	word;
    Palette:	array[1..48] of byte;
    Mode:	byte;
    Planes:	byte;
    BPLine:	word;
    PalInf:	word;
    ShRes:	word;
    SvRes:	word;
    Extra:	array[0..53] of byte
  end;
  Number = array[0..SizeOf( double ) - 1] of byte;
  TSign = array[1..6] of char;

const
  Signature: TSign = 'Mandel';


var
  Pict: file of byte;
  Cnt1, Cnt3: word;
  Temp1, Temp2, Cnt2: byte;
  Buffer: PLine;
  THeader: Header;
  PHeader: array[1..SizeOf( Header )] of byte absolute THeader;
  BlockPal: PBlockPal;
  CodPal: byte;


procedure WriteFile;			{ ������ ����� }
var					{ ��� ���������� ��������������� }
  Name: string[12];			{ �� pict00.pcx �� pict99.pcx }
begin
  Name := 'pict00.pcx';
  repeat
    Assign( Pict, Name );
    Reset( Pict );
    if IOResult = 0 then Close( Pict )
    else Break;
    if Name[6] < '9' then Inc( Name[6] )
    else begin
      Name[6] := '0';
      Inc( Name[5] )
    end
  until False;
  Rewrite( Pict );
  with THeader do begin
    Manuf := $A;
    Ver := 5;
    Code := 1;
    Bits := 8;
    X1 := 0;
    Y1 := 0;
    X2 := MaxX - 1;
    Y2 := MaxY - 1;
    HRes := MaxX;
    VRes := MaxY;
    Mode := 0;
    Planes := 1;
    BPLine := MaxX;
    Move( Signature, Extra, SizeOf( Signature ));
    Move( CenterX^, Extra[SizeOf( Signature )], SizeOf( Number ));
    Move( CenterY^, Extra[SizeOf( Signature ) + SizeOf( Number )],
	  SizeOf( Number ));
    Move( Scale^, Extra[SizeOf( Signature ) + SizeOf( Number ) +
	  SizeOf( Number )], SizeOf( Number ))
  end;
  for Cnt1 := 1 to SizeOf( THeader ) do Write( Pict, PHeader[Cnt1] );
  New( Buffer );
  for Cnt3 := 0 to MaxY - 1 do begin
    GetLine( Buffer, Cnt3 );
    Cnt1 := 0;
    Temp2 := Buffer^[Cnt1];
    Buffer^[MaxX] := not Buffer^[MaxX-1];
    Inc( Cnt1 );
    repeat
      Temp1 := Temp2;
      Cnt2 := 0;
      repeat
	Temp2 := Buffer^[Cnt1];
	Inc( Cnt1 );
	Inc( Cnt2 )
      until ( Temp1 <> Temp2 ) or ( Cnt2 = 63 ) or ( Cnt1 > MaxX );
      if (( Cnt2 = 1 ) and ( Temp1 >= $C0 )) or ( Cnt2 > 1 ) then begin
	Cnt2 := Cnt2 or $C0;
	Write( Pict, Cnt2 )
      end;
      Write( Pict, Temp1 )
    until Cnt1 > MaxX
  end;
  Dispose( Buffer );
  New( BlockPal );
  GetPalette( BlockPal );
  CodPal := $C;
  Write( Pict, CodPal );
  for Cnt1 := 0 to NumPal do begin
    CodPal := BlockPal^[Cnt1] shl 2;
    Write( Pict, CodPal )
  end;
  Dispose( BlockPal );
  Close( Pict )
end;

function ReadFile;
var
  BufPalette: PBlockPal;

begin
  Assign( Pict, Name );
  Reset( Pict );
  ReadFile := False;
  if IOResult <> 0 then Exit;
  for Cnt2 := 1 to SizeOf( Header ) do Read( Pict, PHeader[Cnt2] );
  if Signature <> TSign(  Addr( THeader.Extra )^ ) then begin
    Close( Pict );
    Exit
  end;
  ReadFile := True;
  with THeader do begin
    Move( Extra[SizeOf( Signature )], CenterX^, SizeOf( Number ));
    Move( Extra[SizeOf( Signature ) + SizeOf( Number )], CenterY^,
	    SizeOf( Number ));
    Move( Extra[SizeOf( Signature ) + SizeOf( Number ) + SizeOf( Number )],
	    Scale^, SizeOf( Number ))
  end;
  New( Buffer );
  for Cnt3 := 0 to MaxY - 1 do begin	{ ���� �� ����������� ��� ������ }
    Cnt1 := 0;
    repeat
      Read( Pict, Temp1 );
      if Temp1 >= $C0 then begin	{ ����-����������� }
	Temp2 := Temp1 and $3F;		{ �������� ����� ���������� }
	Read( Pict, Temp1 )		{ ��������� ����������� ���� }
      end else Temp2 := 1;		{ ����� ���������� = 1 }
      for Cnt2 := 1 to Temp2 do begin	{ �������� � ����� ����������� }
	Buffer^[Cnt1] := Temp1;		{ ����� ������������� ������ }
	Inc( Cnt1 )
      end
    until Cnt1 >= MaxX;			{ ���� ������ �� ����������� }
    SetLine( Buffer, Cnt3 )		{ ������� ������ �� ����� }
  end;
  Read( Pict, Temp1 );			{ ����-��������� ������� 256 ������ }
  Dispose( Buffer );
  New( BufPalette );
  for Cnt1 := 0 to NumPal do begin	{ ��������� ���������� � ������� }
    Read( Pict, Temp1 );
    BufPalette^[Cnt1] := Temp1 shr 2	{ ��������� � ������ }
  end;
  SetAllPalette( BufPalette );		{ ����� ����� ���������� ��� ������� }
  Dispose( BufPalette );
  Close( Pict )
end;

end.