Autocad スライドファイル SLD / スライドライブラリ SLB 読み込み 2018/08/05

2018/08/05 スライドライブラリ (slb) の読み込みに対応。WMF、BMP 変換を追加
2018/08/05 ファイルサイズが適当だった、Offset Vector の cad への描画が抜けていたのを修正
2018/07/29 塗りつぶし (Solid) 読み込みに対応
2018/07/28 初版

Autocad Help スライドファイルスライドライブラリ を元に、sld、slb ファイルを Delphi で読んでみました。

|スライドは作図領域の左下コーナーを点 (0, 0) として作成され、
|スライドファイルに書き出される座標とサイズはすべて、ディスプレイ デバイスの作図領域を表します。
なので、スライドを作成するときは、作図領域(グラフィックウィンドウ)を最大に、できればフルスクリーンにすると、
より精度の高いベクトルデータが作成されます。

スライドファイルの用途 (Autocad Help より抜粋)
|・ アプリケーションでプレゼンテーションをする。
|・ ある図面で作業しているときに、別の図面のスナップショットを表示する。
|・ ダイアログ ボックス内のイメージ タイル メニューを作成する。

データファイル
 ・円、円弧等は、微小直線に変換されます。
 ・文字は、線分に分解されます。TrueType の場合、フォントの輪郭が取得できます。(TXTEXP コマンドと同じ感じ)

※サンプルコード Button1Click() では、確認のため Bricscad 上に読み込みデータを作成しています。
 ファイルの読み込みには、不要です。
※サンプルコード Button2Click() では、WMF、BMP に変換します。尺度の変更も可能です。
 SLD 読み込み部分は、Button1Click() と同じです。


unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, ComObj, System.Types;

type
  TSld = record
    Name : string;
    Pos : integer;
  end;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    OpenDialog1: TOpenDialog;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

  // プロトタイプ
// AutoCADの色番号をRGBに変える
function acColorToRGB( acColorIndex : integer): integer;


implementation

{$R *.dfm}

uses
  BricscadApp_TLB, BricscadDb_TLB;

// スライドファイル
procedure TForm1.Button1Click(Sender: TObject);
var
  AFile: TFileStream;
  BR: TBinaryReader;
  fname : TFileName;
  bt : TBytes;
  i : Integer;
  s : string;

  IDstring : string;
  HighXdot : Word;
  HighYdot : Word;
  AspectRatio : double;
  HardwareFill : Word;
  TestNumber : Word;
  NewColor : Word;
  len : integer;
  vecX0, vecY0, vecX1, vecY1 : Cardinal;
  loop : boolean;
  offX, offY, offX0, offY0, offX1, offY1 : Shortint;
  lastX, lastY : Word;

  app : IAcadApplication;
  mspc : IAcadModelSpace;
  aLine : IAcadLine;
  aSolid : IAcadSolid;

  cadFlag : boolean;
  StartPoint, EndPoint : OleVariant;
  vpts: array [0..3] of OleVariant;
  n : Byte;
  k : integer;
begin
  lastX := 0;
  lastY := 0;
  cadFlag := False;
  fname := '';
  Memo1.Lines.Clear;

  OpenDialog1.Filter :='*.sld|*.sld';

  if OpenDialog1.Execute then begin
    Memo1.Lines.Add(OpenDialog1.FileName);
    fname := OpenDialog1.FileName;
  end;
  if fname <> '' then begin
    AFile := TFileStream.Create(fname, fmOpenRead);

    BR := TBinaryReader.Create(AFile, TEncoding.ANSI, false);
    try
      // 読み込む
      bt := BR.ReadBytes(AFile.Size);
      BR.Close;
    finally
      BR.Free;
      AFile.Free;
    end;
  end;
  // 読み込みバイト数
  len := Length(bt);
  if len > 31 then begin
    // 動作確認のため、Bricscad を使う
    try
      cadFlag := Supports(GetActiveOleObject('BricscadApp.AcadApplication'), IAcadApplication, app);
    except
      ;
    end;
    if cadFlag then begin
      mspc := app.ActiveDocument.ModelSpace;
      StartPoint := VarArrayCreate([0, 2], varDouble);
      EndPoint   := VarArrayCreate([0, 2], varDouble);
      for i := 0 to 3 do
        vpts[i] := VarArrayCreate([0, 2], varDouble);
    end;

    Memo1.Lines.Add('ReadBytes = ' + IntToStr(Length(bt)));

    // -----------------------------------------------------------------------
    // ヘッダー
    s := '';
    for i := 0 to 16 do begin
      if bt[i]= 0 then break
      else s := s + Char(bt[i]);
    end;
    // "AutoCAD Slide" CR LF ^Z NUL
    IDstring := Trim(s); // 'AutoCAD Slide'
    Memo1.Lines.Add('IDstring = ' + IDstring);

    // グラフィックス領域の幅: 1 ピクセル単位
    HighXdot := bt[19] + bt[20] * $100;
    Memo1.Lines.Add('HighXdot = ' + HighXdot.ToString);
    // グラフィックス領域の高さ: 1 ピクセル単位
    HighYdot := bt[21] + bt[22] * $100;
    Memo1.Lines.Add('HighYdot = ' + HighYdot.ToString);

    // HighXdot / HighYdot と同じ値
    // 作図領域の縦横比(水平サイズ/垂直サイズ)を 10,000,000 倍した値。
    // この値は、常に最下位バイトから書き出されます。
    AspectRatio := (bt[23] + bt[24] * $100 + bt[25] * $10000 + bt[26] + $1000000) / 10000000;
    Memo1.Lines.Add('AspectRatio = ' + AspectRatio.ToString);
    // 0 または 2(値は重要ではありません)
    HardwareFill := bt[27] + bt[28] * $100;
    Memo1.Lines.Add('HardwareFill = ' + HardwareFill.ToString);
    TestNumber := bt[29] + bt[30] * $100;
    // HEX で 1234
    // スライド内の 2 バイト値がすべて、下位バイトから書き出されるか(Intel 8086 系 CPU)、
    // 上位バイトから書き出されるか(Motorola 68000 系 CPU)を判断するために使用される数値(16 進数の 1234)。
    Memo1.Lines.Add('TestNumber = ' + TestNumber.ToHexString);

    // -----------------------------------------------------------------------
    // データ レコード
    i := 31;
    len := Length(bt);
    loop := True;
    while (i < (len - 1)) and loop do begin

      case bt[i + 1] of
        $00..$7F: begin // ベクトル 8 bytes
          // 通常のベクトルの始点- X、始点- Y、終点-X、終点-Y の順。それぞれ 2 バイト値。
          vecX0 := bt[i+1] * 256 + bt[i];
          vecY0 := bt[i+3] * 256 + bt[i+2];
          vecX1 := bt[i+5] * 256 + bt[i+4];
          vecY1 := bt[i+7] * 256 + bt[i+6];
          // 始点の座標は最後の点として保存
          lastX := vecX0;
          lastY := vecY0;

          Memo1.Lines.Add('Vector = ' + vecX0.ToString +','+vecY0.ToString +' - ' +
            vecX1.ToString +','+vecY1.ToString);
          i := i + 8;

          if cadFlag then begin
            StartPoint[0] := vecX0;
            StartPoint[1] := vecY0;
            EndPoint[0] := vecX1;
            EndPoint[1] := vecY1;
            aline := mspc.AddLine(StartPoint, EndPoint);
            aline.color := NewColor;
          end;
        end;
        $FB: begin // オフセット ベクトル 5 bytes
          // 下位バイトと、それに続く 3 バイトでベクトルの端点(始点-X、始点-Y、終点-X、終点-Y)を表します。
          //  これらの値は、保存されている最後の点からのオフセット(-128 から +127)になります。
          //  計算された始点は、次のベクトルで使用するために、最後の点として保存されます。
          offX0 := bt[i];
          offY0 := bt[i+2];
          offX1 := bt[i+3];
          offY1 := bt[i+4];
          vecX0 := lastX + offX0;
          vecY0 := lastY + offY0;
          vecX1 := lastX + offX1;
          vecY1 := lastY + offY1;

          if cadFlag then begin
            StartPoint[0] := vecX0;
            StartPoint[1] := vecY0;
            EndPoint[0] := vecX1;
            EndPoint[1] := vecY1;
            aline := mspc.AddLine(StartPoint, EndPoint);
            aline.color := NewColor;
          end;
          lastX := vecX0;
          lastY := vecY0;

          Memo1.Lines.Add('Offset vector = ' + vecX0.ToString +','+vecY0.ToString +' - ' +
            vecX1.ToString +','+vecY1.ToString);
          i := i + 5;
        end;
        $FC:begin  //ファイルの終わり 2 bytes
          loop := false;
        end;
        $FD:begin //  塗り潰し図形 6 bytes
          // 下位バイトは常に0(ゼロ)。
          // 次の 2 つの 2 バイト値は、塗り潰し多角形の 1 つの頂点の X および Y の座標を表します。
          // 同様のレコードが 3 から 10 続きます。
          // 塗り潰し図形レコードの Y 座標値が負の場合は、一連のレコードの開始または終了を表します。
          // 開始レコードの X 座標は、後続の頂点レコードの数を表します。
          n := bt[i + 2] + bt[i + 3] * $100; // 後続の頂点レコードの数
          i := i + 6;
          if (n >= 3) and (n <= 10) then begin
            Memo1.Lines.Add('Solid Point Count = ' + n.ToString);

            for k := 0 to n - 1 do begin
              vecX0 := bt[i + 2] + bt[i + 3] * $100;
              vecY0 := bt[i + 4] + bt[i + 5] * $100;
              Memo1.Lines.Add('Solid Points[' + k.ToString + '] = ' + vecX0.ToString + ',' + vecY0.ToString);

              if cadFlag then begin
                if k < 4 then begin
                  vpts[k][0] := vecX0;
                  vpts[k][1] := vecY0;
                end;
                if k = n - 1 then begin
                  if n < 4 then begin
                    vpts[3] := vpts[2];
                  end;
                  aSolid := mspc.AddSolid(vpts[0], vpts[1], vpts[2], vpts[3]);
                  aSolid.color := NewColor;
                end;
              end;

              lastX := vecX0;
              lastY := vecY0;
              i := i + 6;
            end;
            // 頂点データの次のデータを読み飛ばす
            i := i + 6;
          end;
        end;
        $FE: begin  // 連続ベクトル 3 bytes
          // 最後の点から始まるベクトルです。下位バイトとそれに続くバイトは、終点-X と終点-Y を表します。
          // これらは、保存されている最後の点からのオフセット(-128 から +127)です。
          // 計算された点は、次のベクトルに使用するために、最後の点として保存されます。
          offX := bt[i];
          offY := bt[i+2];

          if cadFlag then begin
            StartPoint[0] := lastX;
            StartPoint[1] := lastY;
            EndPoint[0] := lastX + offX;
            EndPoint[1] := lastY + offY;
            aline := mspc.AddLine(StartPoint, EndPoint);
            aline.color := NewColor;
          end;

          Memo1.Lines.Add('Common endpoint vector  = ' + (lastX + offX).ToString +','+ (lastY + offY).ToString);
          lastX := lastX + offX;
          lastY := lastY + offY;
          i := i + 3;
        end;
        $FF: begin // 新しい色 2 bytes
          NewColor := bt[i];
          Memo1.Lines.Add('New color = ' + NewColor.ToString);
          i := i + 2;
        end;
      end;
    end;
  end;
end;

// スライドライブラリ
// スライドライブラリ内のスライドデータは、単独のスライドファイルと同じ
procedure TForm1.Button2Click(Sender: TObject);
var
  AFile: TFileStream;
  BR: TBinaryReader;
  fname : TFileName;
  bt : TBytes;
  i, j : Integer;
  s : string;
  len : integer;
  IDString : string;
  pos : integer;
  sld : array of TSld;
  sldcnt : integer;
  offset : integer;
  loop : boolean;
  endaddr : integer;
  HighXdot : Word;
  HighYdot : Word;
  AspectRatio : double;
  HardwareFill : Word;
  TestNumber : Word;
  NewColor : Word;
  vecX0, vecY0, vecX1, vecY1 : Cardinal;
  offX, offY, offX0, offY0, offX1, offY1 : Shortint;
  lastX, lastY : Word;
  n, k : integer;


  MetaFile : TMetaFile;
  MFCanvas : TMetaFileCanvas;
  Points : array [0..2] of TPoint;
  BMP : TBitmap;
  wmfName : TFileName;
  bmpName : TFileName;

begin
  NewColor := 0;
  HighXdot := 0;
  HighYdot := 0;
  OpenDialog1.Filter :='*.slb|*.slb';
  if OpenDialog1.Execute then begin
    Memo1.Lines.Add(OpenDialog1.FileName);
    fname := OpenDialog1.FileName;
  end;
  if fname <> '' then begin
    AFile := TFileStream.Create(fname, fmOpenRead);

    BR := TBinaryReader.Create(AFile, TEncoding.ANSI, false);
    try
      // 読み込む
      bt := BR.ReadBytes(AFile.Size);
      BR.Close;
    finally
      BR.Free;
      AFile.Free;
    end;
  end;
  // 読み込みバイト数
  len := Length(bt);
  if len > 32 then begin
    // ヘッダー
    s := '';
    for i := 0 to 31 do
      s := s + Char(bt[i]);
    // "AutoCAD Slide Library 1.0" CR LF ^Z NUL NUL NUL NUL  Header (32 bytes)
    IDstring := Trim(s); // 'AutoCAD Slide Library 1.0'

    // とりあえず、4 x 5 = 20 個用意
    SetLength(sld, 20);
    offset := 32;
    for i := 0 to 19 do begin
      s := '';
      for j := 0 to 31 do begin
        if bt[offset + j] = 0 then break
        else s := s + Char(bt[offset + j]);
      end;
      s := Trim(s);
      if s = '' then begin
        // 実際の数に合わせる
        SetLength(sld, i);
        Break;
      end
      else begin
        // SLD データの先頭位置(4bytes)
        pos := bt[offset + 32] + bt[offset + 33] * $100 +
                bt[offset + 34] * $10000 + bt[offset + 35] * $1000000;
        sld[i].Name := s;
        sld[i].Pos := pos;
        offset := offset + 36;
      end;
    end;
    if (Length(sld) > 0) and (HighXdot > 0) and (HighYdot > 0) then begin

      // スライドのデータ取り出し
      for i := 0 to Length(sld) -1 do begin
        MetaFile := TMetaFile.Create;
        try
          MetaFile.Height := HighYdot;
          MetaFile.Width  := HighXdot;

          MFCanvas := TMetaFileCanvas.Create(MetaFile, 0);
          try
            lastX := 0;
            lastY := 0;

            offset := sld[i].Pos;

            s := '';
            for j := 0 to 16 do begin
              if bt[offset + j] = 0 then break
              else s := s + Char(bt[offset + j]);
            end;
            // "AutoCAD Slide" CR LF ^Z NUL
            IDstring := Trim(s); // 'AutoCAD Slide'
            // グラフィックス領域の幅: 1 ピクセル単位
            HighXdot := bt[offset + 19] + bt[offset + 20] * $100;
            // グラフィックス領域の高さ: 1 ピクセル単位
            HighYdot := bt[offset + 21] + bt[offset + 22] * $100;

            // HighXdot / HighYdot と同じ値
            AspectRatio := (bt[offset + 23] + bt[offset + 24] * $100 +
              bt[offset + 25] * $10000 + bt[offset + 26] + $1000000) / 10000000;
            // 0 または 2(値は重要ではありません)
            HardwareFill := bt[offset + 27] + bt[offset + 28] * $100;
            // HEX で 1234
            TestNumber := bt[offset + 29] + bt[offset + 30] * $100;

            MetaFile.Height := HighYdot;
            MetaFile.Width := HighXdot;

            offset := offset + 31;
            loop := True;
            while loop do begin

              case bt[offset + 1] of
                $00..$7F: begin // ベクトル 8 bytes
                  // 通常のベクトルの始点- X、始点- Y、終点-X、終点-Y の順。それぞれ 2 バイト値。
                  vecX0 := bt[offset + 1] * 256 + bt[offset];
                  vecY0 := bt[offset + 3] * 256 + bt[offset + 2];
                  vecX1 := bt[offset + 5] * 256 + bt[offset + 4];
                  vecY1 := bt[offset + 7] * 256 + bt[offset + 6];
                  // 始点の座標は最後の点として保存
                  lastX := vecX0;
                  lastY := vecY0;
                  offset := offset + 8;

                  MFCanvas.Pen.Color := acColorToRGB(NewColor);
                  MFCanvas.MoveTo(vecX0, HighYdot - vecY0);
                  MFCanvas.LineTo(vecX1, HighYdot - vecY1);
                end;
                $FB: begin // オフセット ベクトル 5 bytes
                  offX0 := bt[offset];
                  offY0 := bt[offset + 2];
                  offX1 := bt[offset + 3];
                  offY1 := bt[offset + 4];
                  vecX0 := lastX + offX0;
                  vecY0 := lastY + offY0;
                  vecX1 := lastX + offX1;
                  vecY1 := lastY + offY1;
                  lastX := vecX0;
                  lastY := vecY0;
                  offset := offset + 5;

                  MFCanvas.Pen.Color := acColorToRGB(NewColor);
                  MFCanvas.MoveTo(vecX0, HighYdot - vecY0);
                  MFCanvas.LineTo(vecX1, HighYdot - vecY1);
                end;
                $FC:begin  //ファイルの終わり 2 bytes
                  loop := false;
                end;
                $FD:begin //  塗り潰し図形 6 bytes
                  n := bt[offset + 2] + bt[offset + 3] * $100; // 後続の頂点レコードの数
                  offset := offset + 6;
                  if (n >= 3) and (n <= 10) then begin
                    for k := 0 to n - 1 do begin
                      vecX0 := bt[offset + 2] + bt[offset + 3] * $100;
                      vecY0 := bt[offset + 4] + bt[offset + 5] * $100;

                      lastX := vecX0;
                      lastY := vecY0;
                      offset := offset + 6;

                      if k < 3 then begin
                        Points[k].X := vecX0;
                        Points[k].Y := HighYdot - vecY0;
                      end;
                      if k = n - 1 then begin
                        // 違う?
                        MFCanvas.Brush.Color := acColorToRGB(NewColor);
                        MFCanvas.Polyline(Points);
                      end;
                    end;
                    // 頂点データの次のデータを読み飛ばす
                    offset := offset + 6;
                  end;
                end;
                $FE: begin  // 連続ベクトル 3 bytes
                  offX := bt[offset];
                  offY := bt[offset + 2];

                  MFCanvas.Pen.Color := acColorToRGB(NewColor);
                  MFCanvas.MoveTo(lastX, HighYdot - lastY);
                  MFCanvas.LineTo(lastX + offX, HighYdot - (lastY + offY));

                  lastX := lastX + offX;
                  lastY := lastY + offY;
                  offset := offset + 3;
                end;
                $FF: begin // 新しい色 2 bytes
                  NewColor := bt[offset];
                  offset := offset + 2;
                end;
              end;
            end;
          finally
            MFCanvas.Free;
          end;

          wmfName := ChangeFileExt(fName, '') + '_' + sld[i].Name + '.wmf';
          bmpName := ChangeFileExt(wmfName, '.bmp');

          // 縮小
          MetaFile.SetSize(MetaFile.WIdth div 2, MetaFile.Height div 2);
          // 保存
          MetaFile.SaveToFile(wmfName);
          // ビットマップ
          bmp := TBitmap.Create;
          with bmp do begin
            try
              Height := MetaFile.Height;
              Width := MetaFile.Width;
              Canvas.Brush.Color := clBlack;
              Canvas.FillRect(Rect(0, 0, bmp.Width, bmp.Height));
              Canvas.Draw(0, 0, MetaFile);
              SaveToFile(bmpName);
            finally
              bmp.Free;
            end;
          end;
        finally
          MetaFile.Free;
        end;
      end;
    end;
  end;
end;

// AutoCADの色番号をRGBに変える
function acColorToRGB( acColorIndex : integer): integer;
begin
  case Abs(acColorIndex) of
     1:     result := RGB(255, 0, 0);
     2:     result := RGB(255, 255, 0);
     3:     result := RGB(0, 255, 0);
     4:     result := RGB(0, 255, 255);
     5:     result := RGB(0, 0, 255);
     6:     result := RGB(255, 0, 255);
     7:     result := RGB(255, 255, 255);
     // 7:     result := RGB(0, 0, 0);
     8:     result := RGB(128, 128, 128);
     9:     result := RGB(192, 192, 192);
     10:    result := RGB(255, 0, 0);
     11:    result := RGB(255, 127, 127);
     12:    result := RGB(204, 0, 0);
     13:    result := RGB(204, 102, 102);
     14:    result := RGB(153, 0, 0);
     15:    result := RGB(153, 76, 76);
     16:    result := RGB(127, 0, 0);
     17:    result := RGB(127, 63, 63);
     18:    result := RGB(76, 0, 0);
     19:    result := RGB(76, 38, 38);
     20:    result := RGB(255, 63, 0);
     21:    result := RGB(255, 159, 127);
     22:    result := RGB(204, 51, 0);
     23:    result := RGB(204, 127, 102);
     24:    result := RGB(153, 38, 0);
     25:    result := RGB(153, 95, 76);
     26:    result := RGB(127, 31, 0);
     27:    result := RGB(127, 79, 63);
     28:    result := RGB(76, 19, 0);
     29:    result := RGB(76, 47, 38);
     30:    result := RGB(255, 127, 0);
     31:    result := RGB(255, 191, 127);
     32:    result := RGB(204, 102, 0);
     33:    result := RGB(204, 153, 102);
     34:    result := RGB(153, 76, 0);
     35:    result := RGB(153, 114, 76);
     36:    result := RGB(127, 63, 0);
     37:    result := RGB(127, 95, 63);
     38:    result := RGB(76, 38, 0);
     39:    result := RGB(76, 57, 38);
     40:    result := RGB(255, 191, 0);
     41:    result := RGB(255, 223, 127);
     42:    result := RGB(204, 153, 0);
     43:    result := RGB(204, 178, 102);
     44:    result := RGB(153, 114, 0);
     45:    result := RGB(153, 133, 76);
     46:    result := RGB(127, 95, 0);
     47:    result := RGB(127, 111, 63);
     48:    result := RGB(76, 57, 0);
     49:    result := RGB(76, 66, 38);
     50:    result := RGB(255, 255, 0);
     51:    result := RGB(255, 255, 127);
     52:    result := RGB(204, 204, 0);
     53:    result := RGB(204, 204, 102);
     54:    result := RGB(153, 153, 0);
     55:    result := RGB(153, 153, 76);
     56:    result := RGB(127, 127, 0);
     57:    result := RGB(127, 127, 63);
     58:    result := RGB(76, 76, 0);
     59:    result := RGB(76, 76, 38);
     60:    result := RGB(191, 255, 0);
     61:    result := RGB(223, 255, 127);
     62:    result := RGB(153, 204, 0);
     63:    result := RGB(178, 204, 102);
     64:    result := RGB(114, 153, 0);
     65:    result := RGB(133, 153, 76);
     66:    result := RGB(95, 127, 0);
     67:    result := RGB(111, 127, 63);
     68:    result := RGB(57, 76, 0);
     69:    result := RGB(66, 76, 38);
     70:    result := RGB(127, 255, 0);
     71:    result := RGB(191, 255, 127);
     72:    result := RGB(102, 204, 0);
     73:    result := RGB(153, 204, 102);
     74:    result := RGB(76, 153, 0);
     75:    result := RGB(114, 153, 76);
     76:    result := RGB(63, 127, 0);
     77:    result := RGB(95, 127, 63);
     78:    result := RGB(38, 76, 0);
     79:    result := RGB(57, 76, 38);
     80:    result := RGB(63, 255, 0);
     81:    result := RGB(159, 255, 127);
     82:    result := RGB(51, 204, 0);
     83:    result := RGB(127, 204, 102);
     84:    result := RGB(38, 153, 0);
     85:    result := RGB(95, 153, 76);
     86:    result := RGB(31, 127, 0);
     87:    result := RGB(79, 127, 63);
     88:    result := RGB(19, 76, 0);
     89:    result := RGB(47, 76, 38);
     90:    result := RGB(0, 255, 0);
     91:    result := RGB(127, 255, 127);
     92:    result := RGB(0, 204, 0);
     93:    result := RGB(102, 204, 102);
     94:    result := RGB(0, 153, 0);
     95:    result := RGB(76, 153, 76);
     96:    result := RGB(0, 127, 0);
     97:    result := RGB(63, 127, 63);
     98:    result := RGB(0, 76, 0);
     99:    result := RGB(38, 76, 38);
     100:   result := RGB(0, 255, 63);
     101:   result := RGB(127, 255, 159);
     102:   result := RGB(0, 204, 51);
     103:   result := RGB(102, 204, 127);
     104:   result := RGB(0, 153, 38);
     105:   result := RGB(76, 153, 95);
     106:   result := RGB(0, 127, 31);
     107:   result := RGB(63, 127, 79);
     108:   result := RGB(0, 76, 19);
     109:   result := RGB(38, 76, 47);
     110:   result := RGB(0, 255, 127);
     111:   result := RGB(127, 255, 191);
     112:   result := RGB(0, 204, 102);
     113:   result := RGB(102, 204, 153);
     114:   result := RGB(0, 153, 76);
     115:   result := RGB(76, 153, 114);
     116:   result := RGB(0, 127, 63);
     117:   result := RGB(63, 127, 95);
     118:   result := RGB(0, 76, 38);
     119:   result := RGB(38, 76, 57);
     120:   result := RGB(0, 255, 191);
     121:   result := RGB(127, 255, 223);
     122:   result := RGB(0, 204, 153);
     123:   result := RGB(102, 204, 178);
     124:   result := RGB(0, 153, 114);
     125:   result := RGB(76, 153, 133);
     126:   result := RGB(0, 127, 95);
     127:   result := RGB(63, 127, 111);
     128:   result := RGB(0, 76, 57);
     129:   result := RGB(38, 76, 66);
     130:   result := RGB(0, 255, 255);
     131:   result := RGB(127, 255, 255);
     132:   result := RGB(0, 204, 204);
     133:   result := RGB(102, 204, 204);
     134:   result := RGB(0, 153, 153);
     135:   result := RGB(76, 153, 153);
     136:   result := RGB(0, 127, 127);
     137:   result := RGB(63, 127, 127);
     138:   result := RGB(0, 76, 76);
     139:   result := RGB(38, 76, 76);
     140:   result := RGB(0, 191, 255);
     141:   result := RGB(127, 223, 255);
     142:   result := RGB(0, 153, 204);
     143:   result := RGB(102, 178, 204);
     144:   result := RGB(0, 114, 153);
     145:   result := RGB(76, 133, 153);
     146:   result := RGB(0, 95, 127);
     147:   result := RGB(63, 111, 127);
     148:   result := RGB(0, 57, 76);
     149:   result := RGB(38, 66, 76);
     150:   result := RGB(0, 127, 255);
     151:   result := RGB(127, 191, 255);
     152:   result := RGB(0, 102, 204);
     153:   result := RGB(102, 153, 204);
     154:   result := RGB(0, 76, 153);
     155:   result := RGB(76, 114, 153);
     156:   result := RGB(0, 63, 127);
     157:   result := RGB(63, 95, 127);
     158:   result := RGB(0, 38, 76);
     159:   result := RGB(38, 57, 76);
     160:   result := RGB(0, 63, 255);
     161:   result := RGB(127, 159, 255);
     162:   result := RGB(0, 51, 204);
     163:   result := RGB(102, 127, 204);
     164:   result := RGB(0, 38, 153);
     165:   result := RGB(76, 95, 153);
     166:   result := RGB(0, 31, 127);
     167:   result := RGB(63, 79, 127);
     168:   result := RGB(0, 19, 76);
     169:   result := RGB(38, 47, 76);
     170:   result := RGB(0, 0, 255);
     171:   result := RGB(127, 127, 255);
     172:   result := RGB(0, 0, 204);
     173:   result := RGB(102, 102, 204);
     174:   result := RGB(0, 0, 153);
     175:   result := RGB(76, 76, 153);
     176:   result := RGB(0, 0, 127);
     177:   result := RGB(63, 63, 127);
     178:   result := RGB(0, 0, 76);
     179:   result := RGB(38, 38, 76);
     180:   result := RGB(63, 0, 255);
     181:   result := RGB(159, 127, 255);
     182:   result := RGB(51, 0, 204);
     183:   result := RGB(127, 102, 204);
     184:   result := RGB(38, 0, 153);
     185:   result := RGB(95, 76, 153);
     186:   result := RGB(31, 0, 127);
     187:   result := RGB(79, 63, 127);
     188:   result := RGB(19, 0, 76);
     189:   result := RGB(47, 38, 76);
     190:   result := RGB(127, 0, 255);
     191:   result := RGB(191, 127, 255);
     192:   result := RGB(102, 0, 204);
     193:   result := RGB(153, 102, 204);
     194:   result := RGB(76, 0, 153);
     195:   result := RGB(114, 76, 153);
     196:   result := RGB(63, 0, 127);
     197:   result := RGB(95, 63, 127);
     198:   result := RGB(38, 0, 76);
     199:   result := RGB(57, 38, 76);
     200:   result := RGB(191, 0, 255);
     201:   result := RGB(223, 127, 255);
     202:   result := RGB(153, 0, 204);
     203:   result := RGB(178, 102, 204);
     204:   result := RGB(114, 0, 153);
     205:   result := RGB(133, 76, 153);
     206:   result := RGB(95, 0, 127);
     207:   result := RGB(111, 63, 127);
     208:   result := RGB(57, 0, 76);
     209:   result := RGB(66, 38, 76);
     210:   result := RGB(255, 0, 255);
     211:   result := RGB(255, 127, 255);
     212:   result := RGB(204, 0, 204);
     213:   result := RGB(204, 102, 204);
     214:   result := RGB(153, 0, 153);
     215:   result := RGB(153, 76, 153);
     216:   result := RGB(127, 0, 127);
     217:   result := RGB(127, 63, 127);
     218:   result := RGB(76, 0, 76);
     219:   result := RGB(76, 38, 76);
     220:   result := RGB(255, 0, 191);
     221:   result := RGB(255, 127, 223);
     222:   result := RGB(204, 0, 153);
     223:   result := RGB(204, 102, 178);
     224:   result := RGB(153, 0, 114);
     225:   result := RGB(153, 76, 133);
     226:   result := RGB(127, 0, 95);
     227:   result := RGB(127, 63, 111);
     228:   result := RGB(76, 0, 57);
     229:   result := RGB(76, 38, 66);
     230:   result := RGB(255, 0, 127);
     231:   result := RGB(255, 127, 191);
     232:   result := RGB(204, 0, 102);
     233:   result := RGB(204, 102, 153);
     234:   result := RGB(153, 0, 76);
     235:   result := RGB(153, 76, 114);
     236:   result := RGB(127, 0, 63);
     237:   result := RGB(127, 63, 95);
     238:   result := RGB(76, 0, 38);
     239:   result := RGB(76, 38, 57);
     240:   result := RGB(255, 0, 63);
     241:   result := RGB(255, 127, 159);
     242:   result := RGB(204, 0, 51);
     243:   result := RGB(204, 102, 127);
     244:   result := RGB(153, 0, 38);
     245:   result := RGB(153, 76, 95);
     246:   result := RGB(127, 0, 31);
     247:   result := RGB(127, 63, 79);
     248:   result := RGB(76, 0, 19);
     249:   result := RGB(76, 38, 47);
     250:   result := RGB(51, 51, 51);
     251:   result := RGB(91, 91, 91);
     252:   result := RGB(132, 132, 132);
     253:   result := RGB(173, 173, 173);
     254:   result := RGB(214, 214, 214);
     255:   result := RGB(255, 255, 255);
     // BYLAYEY =  256 or BYBLOCK = 0
     else
       result := RGB(255, 255, 255);
  end;
end;
end.