home *** CD-ROM | disk | FTP | other *** search
- /* Personal Paint Amiga Rexx script - Copyright © 1996, 1997 Cloanto Italia srl */
-
- /* $VER: SaveAnimGif.pprx 1.7 */
-
- /** ENG
- This script saves the current anim-brush as a GIF animation file. Specific
- features of the GIF animation specification can be set through a requester.
-
- This script checks for the differences between frames and only stores
- the smallest rectangular region containing changes. Other techniques
- are employed for additional compression. The resulting GIF animations are
- highly optimized and occupy considerably less space than GIF animations
- created with other tools available on the Amiga.
-
- The "Use Loop" option inserts an "Application Extension Block" into the GIF
- file (as implemented by Netscape in its Navigator software from version 2).
- This additional block, which is interpreted by most other browsers
- supporting GIF animations, specifies that the animation be repeated as many
- times as indicated by the "Loop" value. A value of 0 expressly means
- "loop continuously".
-
- The list of frames shows the timing value for each frame, in seconds/100.
- These values can be selected, edited and applied to one or more frames.
- Alternatively, the timing can be copied automatically from the current
- animation. If this option is selected ("From Animation"), then the
- "Delay" value is used to indicate from which animation frame the timing
- values are to be copied.
-
- The "Transparency" setting indicates the current transparency status of
- the anim-brush. If transparency is not required by the animation, it is
- recommended to leave this option disabled.
-
- Note: an "anim-brush" is a part of a full-screen animation. It can be
- either loaded or defined manually after clicking three times on the
- Define Brush tool.
- */
-
- /** DEU
- Dieses Skript dient zum Speichern des aktuellen Anim-Brushes als
- GIF-Animation. Eine Reihe spezifischer Merkmale des Animationsformats läßt
- sich in einem dazugehörigen Dialogfenster auswählen.
-
- Nach der Skriptausführung werden zwei aufeinanderfolgende Frames zunächst
- auf Unterschiede untersucht. Gespeichert wird dann nur der kleinste
- rechteckige Bereich, der Unterschiede zwischen den beiden Bildern aufweist.
- Außerdem werden zum Erzielen einer weiter verbesserten Komprimierung noch
- andere Verfahren angewendet. Die daraus resultierenden hochoptimierten
- GIF-Animationen benötigen erheblich weniger Speicherplatz als solche, die
- mit anderen für den Amiga erhältlichen Tools erstellt worden sind.
-
- Durch die Option "Schleife aktiv:" wird der GIF-Datei eine
- Programmerweiterung ("Application Extension Block") hinzugefügt, wie sie von
- Netscape im Navigator ab Version 2 implementiert ist. Dieser auch von den
- meisten anderen Browsern, die GIF-Animationen unterstützen, interpretierte
- Block legt fest, daß die Animation so oft wiederholt wird, wie unter
- "Schleife:" angegeben. Ein Wert von 0 bewirkt das Abspielen in einer
- Endlosschleife.
-
- Die Frameliste zeigt den Timingwert für jedes Einzelbild in Hundertstel
- Sekunden. Diese Werte lassen sich auswählen, bearbeiten und anschließend
- einem oder mehreren Einzelbildern zuweisen. Alternativ dazu können die
- Timingwerte automatisch aus der aktuellen Animation kopiert werden. Wenn die
- entsprechende Option aktiviert ist ("Von Animation"), wird der
- "Verzögerung"-Wert verwendet, um anzuzeigen, von welchem Einzelbild der
- Animation die Timingwerte kopiert werden sollen.
-
- Die "Transparenz"-Einstellung gibt den aktuellen Transparenzstatus des
- Animationspinsels wieder. Erfordert die Animation keine Transparenz, so wird
- empfohlen, diese Option ausgeschaltet zu lassen.
-
- Hinweis: Ein Animationspinsel ist ein Bestandteil einer normalen Animation.
- Er läßt sich nach einem Dreifachklick auf das Pinseldefinitionswerkzeug
- entweder laden oder manuell definieren.
- */
-
- /** ITA
- Questo script salva l'anim-brush corrente come un'animazione GIF. Si possono
- impostare le caratteristiche peculiari di una animazione GIF tramite una
- apposita finestra di dialogo.
-
- Questo script controlla eventuali differenze tra fotogrammi e salva solo
- la più piccola regione rettangolare che contiene modifiche. Altre tecniche
- sono utilizzate per una compressione aggiuntiva. Le animazioni GIF risultanti
- sono altamente ottimizzate ed occupano molto meno spazio di quelle create con
- altri programmi disponibili su Amiga.
-
- L'opzione "Usare ciclo" inserisce un "Application Extension Block" nel file GIF
- (come implementato da Netscape nel suo programma Navigator a partire dalla
- versione 2). Questo blocco aggiuntivo, che viene interpretato dalla maggior
- parte degli altri programmi di navigazione che permettono l'uso di animazioni
- GIF, specifica che l'animazione deve essere ripetuta tante volte quante
- indicato dal valore "Ciclo". Un valore pari a 0 significa espressamente
- "ciclo continuo".
-
- L'elenco dei fotogrammi mostra il valore di temporizzazione per ciascun
- fotogramma, in centesimi di secondo. Tali valori possono essere selezionati,
- modificati e applicati a uno o più fotogrammi. In alternativa, la
- temporizzazione può essere copiata automaticamente dall'animazione corrente.
- Se questa opzione è attiva ("Da animazione"), si usa il valore di
- "Temporizzazione fotogrammi" per indicare da quale fotogramma dell'animazione
- si devono copiare i valori di temporizzazione.
-
- L'impostazione di "Trasparenza" indica lo stato attuale della trasparenza
- dell'anim-brush. Se l'animazione non richiede la trasparenza, è consigliabile
- lasciare disattivata questa opzione.
-
- Nota: un "anim-brush" è un pennello, e come tale in genere una (più piccola)
- parte di un'animazione a tutto schermo. Un anim-brush può essere caricare,
- oppure definito manualmente facendo click tre volte sullo strumento
- Definire pennello.
- */
-
- IF ARG(1, EXISTS) THEN
- PARSE ARG PPPORT
- ELSE
- PPPORT = 'PPAINT'
-
- IF ~SHOW('P', PPPORT) THEN DO
- IF EXISTS('PPaint:PPaint') THEN DO
- ADDRESS COMMAND 'Run >NIL: PPaint:PPaint'
- DO 30 WHILE ~SHOW('P',PPPORT)
- ADDRESS COMMAND 'Wait >NIL: 1 SEC'
- END
- END
- ELSE DO
- SAY "Personal Paint could not be loaded."
- EXIT 10
- END
- END
-
- IF ~SHOW('P', PPPORT) THEN DO
- SAY 'Personal Paint Rexx port could not be opened'
- EXIT 10
- END
-
- ADDRESS VALUE PPPORT
- OPTIONS RESULTS
- OPTIONS FAILAT 10000
-
- Get 'LANG'
- IF RESULT = 1 THEN DO /* Deutsch */
- txt_title_req = 'GIF-Anim-Brush speichern'
- txt_title_set = 'GIF-Anim-Brush-Einstellungen'
- txt_title_delay = 'Frame-Verzögerung'
- txt_gad_delay = 'Frame-Verzögerungen:'
- txt_gad_annot = '_Bemerkung:'
- txt_gad_loop = '_Schleife:'
- txt_gad_useloop = 'Schleife ak_tiv:'
- txt_gad_transp = '_Transparenz:'
- txt_gad_del = '_Verzögerung:'
- txt_gad_deltype = ' '
- txt_gad_deltype0 = '1/100\""'
- txt_gad_deltype1 = 'Von Animation'
- txt_gad_from = 'A_b Frame:'
- txt_gad_to = 'Bi_s Frame:'
- txt_err_oldclient = 'Für dieses Skript_ist eine neuere Version_von Personal Paint erforderlich'
- txt_err_oldlib = 'Für dieses Skript ist eine neuere Version_der GIF library erforderlich'
- txt_err_notabsh = 'Aktueller Brush_ist kein Anim-Brush'
- txt_err_notemp = 'Zu wenig Speicher_für temporären Brush'
- txt_err_nomem = 'Speichermangel'
- txt_err_nosave = 'Fehler bei Datei-Ein-/Ausgabe'
- END
- ELSE IF RESULT = 2 THEN DO /* Italiano */
- txt_title_req = 'Scrivere Anim-brush GIF'
- txt_title_set = 'Parametri Anim-brush GIF'
- txt_title_delay = 'Temporizzazione'
- txt_gad_delay = 'Temporizzazione fotogrammi:'
- txt_gad_annot = '_Note:'
- txt_gad_loop = 'Cic_lo:'
- txt_gad_useloop = '_Usare ciclo:'
- txt_gad_transp = '_Transparenza:'
- txt_gad_del = '_Temporizzazione:'
- txt_gad_deltype = ' '
- txt_gad_deltype0 = '1/100\""'
- txt_gad_deltype1 = 'Da animazione'
- txt_gad_from = 'Da _fotogramma:'
- txt_gad_to = 'A f_otogramma:'
- txt_err_oldclient = 'Questa procedura richiede_una versione più recente_di Personal Paint'
- txt_err_oldlib = 'Questa procedura richiede_una versione più recente_della libreria GIF'
- txt_err_notabsh = 'Il pennello attuale_non è un anim-brush'
- txt_err_notemp = 'Impossibile creare_pennello temporaneo'
- txt_err_nomem = 'Memoria insufficiente'
- txt_err_nosave = 'Errore di scrittura'
- END
- ELSE DO /* English */
- txt_title_req = 'Save GIF Anim-Brush'
- txt_title_set = 'GIF Anim-Brush Settings'
- txt_title_delay = 'Frame Delay'
- txt_gad_delay = 'Frame Delays:'
- txt_gad_annot = '_Annotation:'
- txt_gad_loop = '_Loop:'
- txt_gad_useloop = '_Use Loop:'
- txt_gad_transp = '_Transparency:'
- txt_gad_del = '_Delay:'
- txt_gad_deltype = ' '
- txt_gad_deltype0 = '1/100\""'
- txt_gad_deltype1 = 'From Animation'
- txt_gad_from = '_From Frame:'
- txt_gad_to = 'T_o Frame:'
- txt_err_oldclient = 'This script requires a newer_version of Personal Paint'
- txt_err_oldlib = 'This script requires a newer_version of the GIF library'
- txt_err_notabsh = 'The current brush_is not an anim-brush'
- txt_err_notemp = 'No space for temporary brush'
- txt_err_nomem = 'Not enough memory'
- txt_err_nosave = 'File I/O error'
- END
-
- Version 'REXX'
- IF RESULT < 7 THEN DO
- RequestNotify 'PROMPT "'txt_err_oldclient'"'
- EXIT 10
- END
-
- LockGUI
- GetBrushAttributes 'FRAMES'
- frames = RESULT
-
- IF frames < 2 THEN DO
- RequestNotify 'PROMPT "'txt_err_notabsh'"'
- UnlockGUI
- EXIT 0
- END
-
- GetBrushNumber
- bshnum = RESULT
-
- SetCurrentBrush 'UNUSED'
- IF RC ~= 0 THEN DO
- RequestNotify 'PROMPT "'txt_err_notemp'"'
- UnlockGUI
- EXIT 0
- END
- GetBrushNumber
- tbshnum = RESULT
-
- SetCurrentBrush 'BRUSH' bshnum
- GetBrushInfo 'ANNOTATION'
- frame_annot = RESULT
-
- loop = -1
- delay. = 0
- IF WORD(frame_annot, 1) = 'LOOP' & WORD(frame_annot, 3) = 'DELAY' THEN DO
- loop = WORD(frame_annot, 2)
- IF ~DATATYPE(loop, 'W') THEN
- loop = -1
- DO frm = 1 TO frames
- del = WORD(frame_annot, 3+frm)
- IF DATATYPE(del, 'W') THEN
- delay.frm = del
- END
- END
- use_loop = (loop >= 0)
- IF loop < 0 THEN
- loop = 0
-
- fnlen = LENGTH(frames)
- dsel = 1
- do_req = 1
- deltype = 0
-
- GetBrushInfo 'COPYRIGHT'
- annot = RESULT
- max_annot_size = LENGTH(annot) * 2
- IF max_annot_size < 200 THEN
- max_annot_size = 200
-
- GetBrushAttributes 'TRANSPARENCY'
- transp = RESULT
- IF transp ~= 1 THEN
- transp = 0
-
- DO WHILE do_req
- ppos = 1
- DO FOREVER
- ppos = INDEX(annot, '"', ppos)
- IF ppos = 0 THEN BREAK
- annot = INSERT('\"', annot, ppos-1)
- ppos = ppos + 3
- END
-
- req = '"LIST ACTION = ""'txt_gad_delay'"", 'frames', 'dsel-1', 20, 7'
- DO frm = 1 TO frames
- req = req || ', ""'RIGHT(frm, fnlen) || ':' delay.frm || '""'
- END
-
- req = req ||,
- ' STRING = ""'txt_gad_annot'"", 'max_annot_size', ""'annot'"" ' ||,
- ' INTSTR = ""'txt_gad_loop'"", 0, 32767, 'loop' ' ||,
- ' CHECK = ""'txt_gad_useloop'"", 'use_loop' ' ||,
- ' CHECK = ""'txt_gad_transp'"", 'transp' "'
-
- Request 'RESIZE "'txt_title_set'"' req
- IF RC = 0 THEN DO
- dsel = RESULT.1 + 1
- annot = RESULT.2
- loop = RESULT.3
- use_loop = RESULT.4
- transp = RESULT.5
-
- IF RESULT = -1 THEN DO
- Request '"'txt_title_delay'" ' ||,
- '"INTSTR = ""'txt_gad_del'"", 0, 32767, 'delay.dsel' ' ||,
- ' CYCLE = ""'txt_gad_deltype'"", 2, 'deltype', ""'txt_gad_deltype0'"", ""'txt_gad_deltype1'"" ' ||,
- ' SEPARATOR ' ||,
- ' INTSTR = ""'txt_gad_from'"", 1, 'frames', 'dsel' ' ||,
- ' INTSTR = ""'txt_gad_to'"", 1, 'frames', 'dsel' "'
- IF RC = 0 THEN DO
- del = RESULT.1
- deltype = RESULT.2
- frfrom = RESULT.3
- frto = RESULT.4
- frstep = SIGN(frto - frfrom)
- IF frstep = 0 THEN
- frstep = 1
- DO frm = frfrom TO frto BY frstep
- IF deltype THEN DO
- IF del < 1 THEN
- del = 1
- GetFrameDelay 'FRAME' del
- IF RC = 0 THEN
- delay.frm = TRUNC((RESULT * 100 / 60) + 0.5)
- del = del + frstep
- END
- ELSE delay.frm = del
- END
- END
- END
- ELSE do_req = 0
- END
- ELSE DO
- UnlockGUI
- EXIT 0
- END
- END
-
- IF ~use_loop THEN
- loop = -1
- frame_annot = 'LOOP' loop 'DELAY'
- DO frm = 1 TO frames
- frame_annot = frame_annot delay.frm
- END
- SetBrushInfo 'ANNOTATION "'frame_annot'"'
-
-
- RequestFile '"'txt_title_req'" SAVEMODE'
- IF RC = 0 THEN DO
- PARSE VALUE RESULT WITH '"' fname '"'
- tempfile = 'T:PP_AnGif.'PRAGMA('ID')
-
- GetBrushAttributes 'FRAMEFIRST'
- sv_frmin = RESULT
- GetBrushAttributes 'FRAMELAST'
- sv_frmax = RESULT
- GetBrushAttributes 'LENGTH'
- sv_frlen = RESULT
- GetBrushAttributes 'FRAMEPOSITION'
- sv_frpos = RESULT
- Get 'ICONS'
- sv_icons = RESULT
-
- GetBrushAttributes 'WIDTH'
- bwidth = RESULT
- GetBrushAttributes 'HEIGHT'
- bheight = RESULT
-
- GetBrushAttributes 'TRANSPARENTCOLOR'
- transpcol = RESULT
- GetBrushAttributes 'COLORS'
- bcolors = RESULT
- plt_size = bcolors * 3
-
- Get 'PATHBSH'
- PARSE VAR RESULT '"' sv_pathbsh '"'
-
- IF transp = 1 THEN
- pckinfo = '09'x
- ELSE
- pckinfo = '00'x
-
- DO bdepth = 1 TO 8
- IF bcolors = (2 ** bdepth) THEN
- BREAK
- END
-
- tbmap.0 = 0
- tbmap.1 = 0
- tbnum = 0
- gfile_open = 0
- global_plt = ''
- err_msg = ''
-
- SIGNAL ON Break_C
-
- AllocateBitmap bwidth bheight bdepth
- IF RC = 0 THEN DO
- tbmap.0 = RESULT
-
- AllocateBitmap bwidth bheight bdepth
- IF RC = 0 THEN DO
- tbmap.1 = RESULT
-
- SetBrushAttributes 'FRAMEFIRST 1 FRAMELAST' frames 'LENGTH' frames
- Set '"ICONS = 0"'
-
- DO frm = 1 TO frames
- SetCurrentBrush 'BRUSH' bshnum
- IF RC ~= 0 THEN DO
- err_msg = txt_err_nomem
- BREAK
- END
-
- SetBrushAttributes 'FRAMEPOSITION' frm
- IF RC ~= 0 THEN DO
- err_msg = txt_err_nomem
- BREAK
- END
-
- GetBitmap '0 0 BITMAP' tbmap.tbnum 'FROMBRUSH'
- tbnum = 1 - tbnum
-
- GetBrushColors
- local_plt = RESULT
-
- IF frm = 1 THEN DO
- dx0 = 0
- dy0 = 0
- dx1 = bwidth - 1
- dy1 = bheight - 1
- global_plt = local_plt
- END
- ELSE DO
- IF transp = 1 THEN
- GetBrushAttributes 'BOUNDARIES'
- ELSE
- GetBitmapDelta tbmap.0 tbmap.1
-
- PARSE VAR RESULT dx0 dy0 dx1 dy1 .
- IF dx0 < 0 THEN DO
- dx0 = 0
- dy0 = 0
- dx1 = 0
- dy1 = 0
- END
- IF transp ~= 1 & global_plt ~== local_plt THEN DO /* IExplorer bug */
- dx0 = 0
- dy0 = 0
- dx1 = bwidth - 1
- dy1 = bheight - 1
- END
- END
-
- SetCurrentBrush 'BRUSH' tbshnum
- IF RC ~= 0 THEN DO
- err_msg = txt_err_nomem
- BREAK
- END
-
- CopyBrush bshnum dx0 dy0 dx1 dy1 'NOFRAMES'
- IF RC ~= 0 THEN DO
- err_msg = txt_err_nomem
- BREAK
- END
-
- SaveBrush tempfile 'FORCE QUIET NOPROGRESS FORMAT "GIF" OPTIONS "GIF89=1" "PROGDSP=0" "SCRFMT=0"'
- IF RC ~= 0 THEN DO
- IF RC = 46 | RC = 47 THEN
- err_msg = txt_err_oldlib
- ELSE
- err_msg = txt_err_nosave
- BREAK
- END
-
- IF ~OPEN('tfile', tempfile, 'R') THEN DO
- err_msg = txt_err_nosave
- BREAK
- END
-
- IF frm = 1 THEN DO
- IF ~OPEN('gfile', fname, 'W') THEN DO
- err_msg = txt_err_nosave
- BREAK
- END
- gfile_open = 1
- data = READCH('tfile', 13) /* sign + screen descriptor */
- bxpix = BITOR(BITAND(SUBSTR(data, 11, 1), '07'x), '80'x)
- CALL WRITECH('gfile', data)
-
- plt_data = READCH('tfile', plt_size) /* palette */
- CALL WRITECH('gfile', plt_data)
- do_plt = 0
-
- IF use_loop THEN
- CALL WRITECH('gfile', '21FF0B'x || 'NETSCAPE2.0' || '0301'x || IntelWord(loop) || '00'x)
-
- IF annot ~= '' THEN DO /* annotation */
- CALL WRITECH('gfile', '21FE'x)
- alen = LENGTH(annot)
- apos = 1
- DO WHILE alen > 0
- IF alen <= 255 THEN
- aln = alen
- ELSE
- aln = 255
- CALL WRITECH('gfile', D2C(aln) || SUBSTR(annot, apos, aln))
- apos = apos + aln
- alen = alen - aln
- END
- CALL WRITECH('gfile', '00'x)
- END
- END
- ELSE DO
- CALL SEEK('tfile', 13, 'B')
- plt_data = READCH('tfile', plt_size)
- do_plt = (global_plt ~== local_plt)
- END
-
- DO FOREVER
- code = READCH('tfile', 1)
-
- IF code = ',' THEN DO /* image */
- /* gfx control */
- CALL WRITECH('gfile', '21F904'x || pckinfo || IntelWord(delay.frm) || D2C(transpcol) || '00'x)
-
- data = READCH('tfile', 9) /* Get image descriptor */
- imginfo = SUBSTR(data, 9, 1)
- IF do_plt THEN
- imginfo = BITOR(BITAND(imginfo, '40'x), bxpix)
-
- /* image descriptor */
- CALL WRITECH('gfile', ',' || IntelWord(dx0) || IntelWord(dy0) || IntelWord(dx1-dx0+1) || IntelWord(dy1-dy0+1) || imginfo)
-
- IF do_plt THEN
- CALL WRITECH('gfile', plt_data)
-
- tpos = SEEK('tfile', 0, 'C')
- epos = SEEK('tfile', 0, 'E')
- dsize = epos - tpos - 1
- CALL SEEK('tfile', tpos, 'B')
-
- /* image data */
- DO WHILE dsize > 0
- IF dsize > 65000 THEN
- tsize = 65000
- ELSE
- tsize = dsize
- data = READCH('tfile', tsize)
- CALL WRITECH('gfile', data)
- dsize = dsize - tsize
- END
- BREAK
- END
- ELSE IF code = '!' THEN DO /* extension */
- CALL SEEK('tfile', 1, 'C')
- length = 1
- DO WHILE length ~= 0
- length = C2D(READCH('tfile', 1))
- IF length > 0 THEN
- CALL SEEK('tfile', length, 'C')
- END
- END
- ELSE BREAK
- END
-
- CALL CLOSE('tfile')
- END
-
- CALL WRITECH('gfile', ';')
- CALL CLOSE('gfile')
- gfile_open = 0
-
- ADDRESS COMMAND 'Delete >NIL: 'tempfile
-
- SetCurrentBrush 'BRUSH' tbshnum
- IF RC = 0 THEN
- FreeBrush 'FORCE'
-
- SetCurrentBrush 'BRUSH' bshnum
- IF RC = 0 THEN
- SetBrushAttributes 'FRAMEFIRST' sv_frmin 'FRAMELAST' sv_frmax 'LENGTH' sv_frlen 'FRAMEPOSITION' sv_frpos
-
- Set '"ICONS =' sv_icons '"'
-
- FreeBitmap tbmap.1
- END
- ELSE err_msg = txt_err_nomem
-
- FreeBitmap tbmap.0
- END
- ELSE err_msg = txt_err_nomem
-
- IF err_msg ~= '' THEN
- RequestNotify 'PROMPT "'err_msg'"'
-
- Set '"PATHBSH=""'sv_pathbsh'"" "'
- END
- UnlockGUI
-
- EXIT 0
-
-
-
-
- IntelWord: PROCEDURE
-
- value = ARG(1)
-
- hibyte = value % 256
- lobyte = value - (hibyte * 256)
-
- RETURN D2C(lobyte) || D2C(hibyte)
-
-
-
-
- Break_C:
-
- IF gfile_open THEN
- CALL CLOSE('gfile')
-
- ADDRESS COMMAND 'Delete >NIL: 'tempfile
-
- SetCurrentBrush 'BRUSH' tbshnum
- IF RC = 0 THEN
- FreeBrush 'FORCE'
-
- SetCurrentBrush 'BRUSH' bshnum
- IF RC = 0 THEN
- SetBrushAttributes 'FRAMEFIRST' sv_frmin 'FRAMELAST' sv_frmax 'LENGTH' sv_frlen 'FRAMEPOSITION' sv_frpos
-
- Set '"ICONS =' sv_icons '"'
-
- IF tbmap.1 ~= 0 THEN
- FreeBitmap tbmap.1
-
- IF tbmap.0 ~= 0 THEN
- FreeBitmap tbmap.0
-
- Set '"PATHBSH=""'sv_pathbsh'"" "'
-
- RETURN
-