home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / grafik / gif / giflesen / giflesen.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1991-02-22  |  10.2 KB  |  435 lines

  1. { ---------------------------------------------------------------------- }
  2. { Aufruf von GIFLESEN:                                                   }
  3. { C:\>giflesen.exe <filename>.GIF [RETURN]                               }
  4. { oder                                                                   }
  5. { C:\>giflesen.exe [RETURN]                                              }
  6. { ---------------------------------------------------------------------- }
  7.  
  8. {$A+,B-,D+,E+,F-,I-,L+,N+,O-,R-,S-,V-}
  9. {$M 64000,0,655360}
  10.  
  11. { Programm lädt Gif-Format und stellt dieses auf einer
  12.   VGA-Karte dar.                                                         }
  13.  
  14.  
  15.  
  16. Uses Dos, Crt;
  17.  
  18. Const  Gif_Kennung           = 'GIF87a';
  19.        MaxTablaenge          = 4096 - 1;
  20.        Modulo_Tabelle        : array [ 1 .. 12 ] of Word
  21.                              = (  $01 ,  $03 ,  $07 ,  $0F ,  $1F ,  $3F ,
  22.                                   $7F ,  $FF , $1FF , $3FF , $7FF , $FFF    );
  23.  
  24. Var    Datei            : File of char;
  25.        reg              : registers;
  26.        Bildbreite ,
  27.        Bildhoehe ,
  28.        Farbbits ,
  29.        Pixelbits ,
  30.        Hintergrundfarbe ,
  31.        Naechste_Grenze ,
  32.        Zeichen ,
  33.        Altes_Zeichen ,
  34.        Geschehen ,
  35.        X_Kor ,
  36.        X_Min ,
  37.        X_Max ,
  38.        Y_Kor ,
  39.        Y_Min ,
  40.        Y_Max ,
  41.        Kontrollzaehler  : Integer;
  42.  
  43.        Naechster_Code ,
  44.        Start_Zeiger ,
  45.        Ende_Code ,
  46.        Init_Code        : Word;
  47.  
  48.        Lese_Buffer      : Longint;
  49.  
  50.        Buffer_Zeiger ,
  51.        Lese_Bits        : Byte;
  52.  
  53.        Globale_Farben   : Boolean;
  54.        Interlay         : Boolean;
  55.        Ende_Komp        : Boolean;
  56.        Ende             : Boolean;
  57.  
  58.        Stack            : array [ 0 .. 4096 ] of Word;
  59.  
  60.        Tabelle          : array [ 0 .. MaxTablaenge ] of Record
  61.                                                             First  : Word;
  62.                                                             Last   : Word;
  63.                                                             Link   : Integer;
  64.                                                          End;
  65.  
  66.  
  67. { Start initialsisierung aller Variabeln mit festem Startwert.              }
  68. Procedure Start_Init;
  69. Var Zaehler : Word;
  70. begin
  71.    for Zaehler := 0 to 4096 do
  72.       Stack [ Zaehler ]  := 0;
  73.  
  74.    Buffer_Zeiger   := 0;
  75.    Lese_Buffer     := 0;
  76.    X_Kor           := 0;
  77.    Y_Kor           := 0;
  78.    Kontrollzaehler := 0;
  79.    Interlay        := FALSE;
  80.    Ende_Komp       := FALSE;
  81.    Ende            := FALSE;
  82. end;
  83.  
  84.  
  85. Procedure Abbruch ( Grafik : Boolean; Texte : String );
  86. Var Dummy : Integer;
  87. begin
  88.    if Grafik then
  89.       TextMode( Co80 );
  90.  
  91.    {$I-}
  92.       close   ( Datei );
  93.    {$I+}
  94.  
  95.    Dummy := IOResult;
  96.  
  97.    writeln ( Texte , #7 );
  98.  
  99.    halt( IOResult );
  100. end;
  101.  
  102.  
  103.  
  104. Function Lese_Zeichen : Byte;
  105. Var Zeichen : Char;
  106. begin
  107.     read ( Datei , Zeichen );
  108.     Lese_Zeichen := ord ( Zeichen );
  109. end;
  110.  
  111.  
  112. { Datei mit dem in der Kommandozeile angegebenem Namen öffnen.           }
  113. { Falls kein Name angegeben ist, diesen vom Benutzer eingeben lassen.    }
  114. Procedure Datei_oeffnen;
  115. Var Datei_Name  : String;
  116. begin
  117.    Writeln;
  118.    Writeln;
  119.    if Paramcount = 0 then
  120.    begin
  121.         repeat
  122.               Write  ( 'Bitte Dateiname eingeben : ');
  123.               readln ( Datei_Name );
  124.         until Datei_Name <> '';
  125.    end
  126.    else
  127.         Datei_Name := Paramstr ( 1 );
  128.  
  129.    {$I-}
  130.       assign ( Datei , Datei_Name );
  131.       reset  ( Datei );
  132.    {$I+}
  133.  
  134.    if IOResult <> 0 then
  135.       Abbruch ( FALSE , 'Falscher Dateiname, Datei nicht vorhanden oder Datei kaputt' );
  136. end;
  137.  
  138.  
  139. Procedure Tabelle_initialisieren ( Zeiger : Word );
  140. Var Zaehler : Word;
  141. begin
  142.     Lese_Bits       := Pixelbits + 1;
  143.     Naechster_Code  := Zeiger + 2;
  144.     Naechste_Grenze := Zeiger shl 1;
  145.  
  146.     Zaehler := 0;
  147.  
  148.     while Zaehler < Zeiger do
  149.     begin
  150.        Tabelle [ Zaehler ].First := Zaehler;
  151.        Tabelle [ Zaehler ].Last  := Zaehler;
  152.        Tabelle [ Zaehler ].Link  := -1;
  153.        inc ( Zaehler );
  154.     end;
  155.  
  156.     while Zaehler <= MaxTablaenge do
  157.     begin
  158.        Tabelle [ Zaehler ].Link := -2;
  159.        inc ( Zaehler );
  160.     end;
  161. end;
  162.  
  163.  
  164. Function Hole_Code ( Bitlaenge : Byte ) : Longint;
  165. begin
  166.    while Buffer_Zeiger < Bitlaenge do
  167.    begin
  168.       if Kontrollzaehler = 0 then
  169.       begin
  170.          Kontrollzaehler := ord ( Lese_Zeichen );
  171.  
  172.          if Kontrollzaehler = 0 then
  173.          begin
  174.             Ende_Komp := TRUE;
  175.             Exit;
  176.          end;
  177.       end;
  178.  
  179.       dec ( Kontrollzaehler );
  180.       Lese_Buffer := Lese_Buffer + Longint ( Lese_Zeichen ) shl Buffer_Zeiger;
  181.       inc ( Buffer_Zeiger , 8 );
  182.    end;
  183.  
  184.    Hole_Code   := Lese_Buffer and Modulo_Tabelle [ Bitlaenge ];
  185.    Lese_Buffer := Lese_Buffer shr Bitlaenge;
  186.  
  187.    dec ( Buffer_Zeiger , Bitlaenge );
  188. end;
  189.  
  190.  
  191. Procedure Fuege_Code_ein ( Code , Alter_Code : Integer;
  192.                            Var Lese_Bits     : Byte      );
  193. begin
  194.    Tabelle [ Naechster_Code ].Link  := Alter_Code;
  195.    Tabelle [ Naechster_Code ].Last  := Tabelle [ Code       ].First;
  196.    Tabelle [ Naechster_Code ].First := Tabelle [ Alter_Code ].First;
  197.  
  198.    inc ( Naechster_Code );
  199.  
  200.    if ( Naechster_Code = Naechste_Grenze ) then
  201.    begin
  202.       if Lese_Bits < 12 then
  203.       begin
  204.          inc ( Lese_Bits );
  205.          Naechste_Grenze := Naechste_Grenze shl 1;
  206.       end;
  207.    end;
  208. end;
  209.  
  210.  
  211. Procedure Punktausgabe ( Farbe : Byte );
  212. begin
  213.    Mem[$A000:(Y_Kor*320+X_Kor)] := Farbe;
  214.  
  215.    inc ( X_Kor );
  216.  
  217.    if X_Kor >= X_Max then
  218.    begin
  219.       X_Kor := X_Min;
  220.  
  221.       if Interlay then
  222.       begin
  223.          inc ( Y_Kor , 8 );
  224.  
  225.          if Y_Kor >= Y_Max then
  226.             dec ( Y_Kor , Y_Max - Y_Min - 1 );
  227.       end
  228.       else
  229.          inc ( Y_Kor );
  230.    end;
  231. end;
  232.  
  233.  
  234.  
  235. Procedure Ausgabe ( Code : Integer );
  236. Var Hilfe ,
  237.     Stackzeiger : Integer;
  238. begin
  239.    Stackzeiger := 0;
  240.  
  241.    repeat
  242.       Stack [ Stackzeiger ] := Tabelle [ Code ].Last;
  243.       inc ( Stackzeiger );
  244.  
  245.       Code := Tabelle [ Code ].Link;
  246.    until Code = -1;
  247.  
  248.    repeat
  249.       dec ( Stackzeiger );
  250.       Punktausgabe ( Stack [ Stackzeiger ] );
  251.    until Stackzeiger <= 0;
  252. end;
  253.  
  254.  
  255. Procedure Farben_setzen;
  256. Var Zaehler : Byte;
  257.     Farben  : array [ 0 .. 255 ] of Record
  258.                                        Rot ,
  259.                                        Gruen ,
  260.                                        Blau    : Byte;
  261.                                     end;
  262. begin
  263.    for Zaehler := 0 to 1 shl Pixelbits - 1 do
  264.    begin
  265.       Farben[ Zaehler ].Rot   := ord ( Lese_Zeichen ) div 4;
  266.       Farben[ Zaehler ].Gruen := ord ( Lese_Zeichen ) div 4;
  267.       Farben[ Zaehler ].Blau  := ord ( Lese_Zeichen ) div 4;
  268.    end;
  269.  
  270.      reg.ah := $10;
  271.      reg.al := $12;
  272.      reg.bx := 1;
  273.      reg.cx := 255;
  274.      reg.es := seg( Farben );
  275.      reg.dx := ofs( Farben ) + 3;
  276.      Intr( $10, reg );
  277. end;
  278.  
  279.  
  280. Procedure Image_Deskriptor;
  281. begin
  282.    X_Min := Lese_Zeichen;
  283.    X_Min := X_Min + Lese_Zeichen * 256;
  284.    Y_Min := Lese_Zeichen;
  285.    Y_Min := Y_Min + Lese_Zeichen * 256;
  286.    X_Max := Lese_Zeichen;
  287.    X_Max := X_Max + Lese_Zeichen * 256;
  288.    Y_Max := Lese_Zeichen;
  289.    Y_Max := Y_Max + Lese_Zeichen * 256;
  290.  
  291.    X_Kor := X_Min;
  292.    Y_Kor := Y_Min;
  293.  
  294.    Zeichen := Lese_Zeichen;
  295.    Zeichen := Lese_Zeichen;
  296.    if ( Zeichen and 64 ) = 64 then
  297.       Interlay := TRUE;
  298.  
  299.    if ( Zeichen shr 7 = 1 ) and Globale_Farben then
  300.       Farben_setzen;
  301. end;
  302.  
  303.  
  304. Procedure Lesen_dekomp;
  305. Var Zaehler ,
  306.     Ende : Integer;
  307. begin
  308.    Image_Deskriptor;
  309.  
  310.    Lese_Bits := Pixelbits + 1;
  311.  
  312.    Init_Code := 1 shl Pixelbits;
  313.    Ende_Code := Init_Code + 1;
  314.    Lese_Bits := Pixelbits + 1;
  315.    Tabelle_initialisieren ( Init_Code );
  316.    Altes_Zeichen := -1;
  317.    Ende := 0;
  318.    Geschehen := 0;
  319.  
  320.    repeat
  321.       Zeichen := Hole_Code ( Lese_Bits );
  322.  
  323.        if Zeichen = Init_Code then
  324.        begin
  325.            Tabelle_initialisieren ( Init_Code );
  326.            Lese_Bits := Pixelbits + 1;
  327.            Altes_Zeichen := -1;
  328.        end
  329.        else
  330.        begin
  331.           if Zeichen = Ende_Code then
  332.              Ende := -1
  333.           else
  334.           begin
  335.              if Tabelle [ Zeichen ].Link <> -2 then
  336.              begin
  337.                 if Altes_Zeichen <> -1 then
  338.                    Fuege_Code_ein ( Zeichen , Altes_Zeichen , Lese_Bits );
  339.              end
  340.              else
  341.              begin
  342.                 Fuege_Code_ein ( Altes_Zeichen , Altes_Zeichen , Lese_Bits );
  343.              end;
  344.  
  345.              Ausgabe ( Zeichen );
  346.              Altes_Zeichen := Zeichen;
  347.           end;
  348.        end;
  349.    until Ende = -1;
  350. end;
  351.  
  352.  
  353. Procedure Grafik_initialisieren;
  354. var t : integer;
  355.     tr : boolean;
  356. begin
  357.      reg.ah := $00;
  358.      reg.al := $13;
  359.      Intr($10,reg);
  360. end;
  361.  
  362.  
  363. Procedure Screen_Deskriptor_lesen;
  364. Var    Zaehler : Integer;
  365.        Zeichen : Byte;
  366. Const  Test    : String = '';
  367. begin
  368.    for Zaehler := 1 to 6 do
  369.       Test := Test + chr ( Lese_Zeichen );
  370.  
  371.    if Test <> Gif_Kennung then
  372.       Abbruch ( TRUE , 'Datei hat kein gültiges Gif-Format' );
  373.  
  374.    Bildbreite := ord ( Lese_Zeichen );
  375.    Bildbreite := Bildbreite + ord ( Lese_Zeichen ) * 256;
  376.    Bildhoehe  := ord ( Lese_Zeichen );
  377.    Bildhoehe  := Bildhoehe + ord ( Lese_Zeichen ) * 256;
  378.  
  379.    Zeichen := Lese_Zeichen;
  380.    if Zeichen shr 7 = 1 then
  381.       Globale_Farben := TRUE
  382.    else
  383.       Globale_Farben := false;
  384.  
  385.    Farbbits     := ( Zeichen shr 4 ) mod 8 + 1;
  386.    Pixelbits    :=   Zeichen mod 8 + 1;
  387.  
  388.    Start_Zeiger := 1 shl Pixelbits + 2;
  389.  
  390.    Hintergrundfarbe := ord ( Lese_Zeichen );
  391.  
  392.    Zeichen := Lese_Zeichen;
  393. end;
  394.  
  395.  
  396. Procedure Gif_Extendet;
  397. begin
  398. end;
  399.  
  400.  
  401. begin
  402.    { Start initialsisierung aller Variabeln mit festem Startwert.           }
  403.    Start_Init;
  404.  
  405.    { Datei mit dem in der Kommandozeile angegebenem Namen öffnen.           }
  406.    { Falls kein Name angegeben ist, diesen vom Benutzer eingeben lassen.    }
  407.    Datei_oeffnen;
  408.  
  409.    Grafik_initialisieren;
  410.  
  411.    Screen_Deskriptor_lesen;
  412.  
  413.    if Globale_Farben then
  414.       Farben_setzen;
  415.  
  416.    repeat
  417.       Zeichen := Lese_Zeichen;
  418.  
  419.       case chr ( Zeichen ) of
  420.          ','   :   Lesen_Dekomp;
  421.  
  422.          '!'   :   Gif_Extendet;
  423.  
  424.          ';'   :   Ende := TRUE;
  425.       end;
  426.    until Ende;
  427.  
  428.    close (  Datei );
  429.  
  430.    write ( #7 );
  431.    repeat until keypressed;
  432.    write(readkey);
  433.  
  434.    TextMode( Co80 );
  435. end.