Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 6155 → Rev 6581

/data/common/media/grafx2/fonts/5pxtinyfont.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/8pxfont.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/GrafX2_Black.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/GrafX2_Dark.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Arma_5__.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Easta_7_.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Easta_7__.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Ronda_7__.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Tempesta_5.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Tempesta_5_.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Tempesta_5__.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Tempesta_5___.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Tempesta_7.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Tempesta_7_.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Tempesta_7__.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Tempesta_7___.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Westa_7_.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/PF_Westa_7__.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/Tuffy.ttf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/fonts/colorfont.pcx
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/gfx2.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/gfx2.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/gfx2def.ini
0,0 → 1,420
###### GrafX2 initialization file ###### Fichier d'initialisation de GrafX2 ##
# # # #
# You may modify this file with any # Vous pouvez modifier ce fichier avec #
# standard ASCII text editor. # n'importe quel éditeur de texte #
# # ASCII standard. #
# # #
# Comments are preceded by ';' or # Les commentaires sont précédés par #
# '#'. # ';' ou '#'. #
# # #
# Options are not case sensitive and # Les options ne sont pas sensibles à #
# spaces are ignored. # la casse et les espaces sont ignorés.#
# # #
# You must not change the order of # Vous ne devez pas changer l'ordre #
# the sections and their options. # des sections et de leurs options. #
# You must not delete or put into # Vous ne devez pas effacer ou mettre #
# comment any section nor option. # en commentaire une section ou option.#
# # #
# Each option is preceded by a # Chaque option est précédée par un #
# comment which explains its meaning. # commentaire qui explique sa fonction.#
# # #
##############################################################################
 
 
 
[MOUSE] # [SOURIS]
 
; The sensitivity of the mouse can | La sensibilité de la souris peut
; take values from 1 to 4. The | prendre des valeurs de 1 à 4. Plus
; smaller values, the faster. | les valeurs sont petites, plus c'est
; This only takes effect in | rapide. Ce paramétrage n'est utilisé
; fullscreen modes. | que dans les modes "plein écran".
; |
X_sensitivity = 1 ; (default 1)
Y_sensitivity = 1 ; (default 1)
 
; Unused setting, only kept for compatibility.
X_correction_factor = 0 ; (default 0)
Y_correction_factor = 0 ; (default 0)
 
; Aspect of the main cursor (cross) | Aspect du curseur principal (croix)
; 1: Solid | 1: Solide
; 2: Transparent | 2: Transparent
; 3: Thin (solid) | 3: Fin (solide)
Cursor_aspect = 1 ; (default 1)
 
[MENU] # [MENU]
 
; Colors of the menus (the black | Couleurs des menus (la couleur noire
; and the white colors cannot be | et la couleur blanche ne peuvent pas
; modified). | être modifiées).
; Values are in {Red,Green,Blue} | Les valeurs sont dans l'ordre {Rouge,
; order and are between 0 and 63. | Vert,Bleu} et vont de 0 à 63.
Light_color = 42,42,42 ; (default 42,42,42)
Dark_color = 27,27,27 ; (default 27,27,27)
;
; Light_color = 24,25,30 ; \_ Nightmare
; Dark_color = 13,14,19 ; /
;
; Light_color = 10,45,28 ; \_ Forest
; Dark_color = 5,27,12 ; /
;
; Light_color = 48,41,26 ; \_ Gold
; Dark_color = 26,22,15 ; /
;
; Light_color = 10,40,55 ; \_ Oceanic
; Dark_color = 10,20,32 ; /
 
; Aspect ratio and size of the | Proportion des menus et de la barre
; menus and the tool-bar. | d'outils.
; Possible values: | Valeurs possibles:
; 0: Do not adapt (pixels are not | 0: Ne pas adapter (les pixels ne sont
; stretched) | pas étirés)
; 1: Adapt the menus and the tool- | 1: Adapter les menus et la barre
; bar according to the resolution| d'outils suivant la résolution
; 2: Slightly adapt the ratio of | 2: Adapter légèrement les proportions
; the menus and tool-bar | des menus et de la barre d'outils
; -1:Do not adapt (like 0) | -1:Ne pas adapter (comme 0)
; -2:Stretch by x2 maximum | -2:Etire au double de taille si possible
; -3:Stretch by x3 maximum | -3:Etire au triple de taille si possible
; -4:Stretch by x4 maximum | -3:Etire au quadruple de taille si
; | possible.
Menu_ratio = -2 ; (default -2)
 
[FILE_SELECTOR] # [SELECTEUR_DE_FICHIERS]
 
; Show hidden files and | Afficher les fichiers et répertoires
; directories (values are 'yes' or | cachés (les valeurs sont 'yes' ou
; 'no'). | 'no').
Show_hidden_files = no ; (default 'no')
Show_hidden_directories = no ; (default 'no')
 
; Delay before displaying a preview | Délai avant d'afficher une preview
; in file-selectors (in 18.2th of | dans les sélecteurs de fichiers (en
; second). Possible values range | 18.2èmes de seconde) Les valeurs
; from 1 to 256. | possibles vont de 1 à 256.
Preview_delay = 8 ; (default 8)
 
; Maximize the preview of the | Maximiser la preview des images pour
; pictures so that it is as big as | qu'elle soit aussi grande que
; possible. If you're not in the | possible.
; same resolution as the picture's | Si vous n'êtes pas dans la même réso-
; one, it can try to correct the | lution que celle de l'image, cela peut
; aspect ratio, but if the picture | essayer de corriger les proportions,
; does not fill the whole screen, | mais si l'image ne prend pas tout
; it can be worse. | l'écran, cela peut être pire.
Maximize_preview = no ; (default 'no')
 
; This option is used to place the | Cette option est utilisée pour placer
; selection bar on a filename by | la barre de sélection sur un nom de
; typing its first letters. | fichier en tapant ses 1ères lettres.
; For example, if you want to find | Par exemple, si vous voulez trouver le
; the "PICTURE.PKM" in a directory | fichier "PICTURE.PKM" dans un réper-
; that also contains "PALETTE.PAL", | toire contenant également le fichier
; you'll just have to type P and I. | "PALETTE.PAL", vous n'aurez qu'à taper
; The different values of "FFF" | P puis I.
; indicate if you want to find the | Les different valeurs de "FFF"
; name in both files and directories| indiquent si vous voulez trouvez le nom
; or just in only one of these: | dans les fichiers ET les répertoires ou
; 0: files and directories | simplement dans l'un OU l'autre.
; 1: files only | 0: fichiers et répertoires
; 2: directories only | 1: fichiers seulement
; | 2: répertoires seulement
Find_file_fast = 0 ; (default 0)
 
 
[LOADING] # [CHARGEMENT]
 
; Automatically set the resolution | Passer automatiquement dans la bonne
; when loading a picture. | résolution lors du chargement d'une
; You should set this value to | image.
; 'yes' after disabling the video | Vous devriez définir cette option à
; modes that are not supported by | 'yes' après avoir inhibé les modes
; your video card or monitor. | vidéo qui ne sont pas supportés par
; | votre matériel.
Auto_set_resolution = no ; (default 'no')
 
; If the variable above is set to | Si la variable ci-dessus est à 'yes',
; 'yes', this one tells if you want | celle-ci indique si vous voulez
; to set the resolution according | définir la résolution suivant:
; to: | 1: les dimensions de "l'écran
; 1: the internal "original screen" | d'origine" internes à l'image
; dimensions of the picture | 2: les véritables dimensions de
; 2: the actual dimensions of the | l'image
; picture |
Set_resolution_according_to = 1 ; (default 1)
 
; If you load a picture with a | Si vous chargez une image ayant une
; palette of less than 256 colors, | palette de moins de 256 couleurs,
; this option defines if you want | cette option indique si vous souhaitez
; to clear the palette or to keep | effacer la palette ou bien conserver
; the colors of the previous | les couleurs de l'image précédente qui
; picture that are over the number | se situent au-delà du nombre de la
; of colors of the new picture. | nouvelle image.
; For example, if you load a | Par exemple, si vous chargez une image
; 32-color picture, the colors 32 | de 32 couleurs, les couleurs 32 à 255
; to 255 will be set to black if | seront passées en noir si cette option
; this option is set to 'yes', or | est à 'yes', ou bien elles resteront
; they will be kept unchanged if | inchangées si elle est à 'no'.
; this option is set to 'no'. |
Clear_palette = yes ; (default 'yes')
 
 
[MISCELLANEOUS] # [DIVERS]
 
; Draw the limits of the picture. | Afficher les limites de l'image
Draw_limits = yes ; (default 'yes')
 
; Adjust the brush grabbing in | Ajuster la capture de brosse en mode
; "grid" mode. | "grille".
Adjust_brush_pick = yes ; (default 'yes')
 
; Coordinates: | Coordonnées:
; 1: Relative | 1: Relatives
; 2: Absolute | 2: Absolues
Coordinates = 1 ; (default 1)
 
; Create a backup file when saving. | Créer un fichier backup lors des
; | sauvegardes.
Backup = no ; (default 'no')
 
; Number of pages stored in memory | Nombre de pages stockées en mémoire
; for "undoing". | destinées à annuler les dernières
; Values are between 1 and 99. | modifications. Valeurs entre 1 et 99.
Undo_pages = 20 ; (default 20)
 
; Speed of the scroll-bars (in VBLs | Vitesse des barre de défilement (en
; waited) while clicking with the | VBLs attendus) lorsque l'un des
; left or right button of the mouse.| boutons de la souris est enfoncé.
; Values can be between 1 and 255. | Les valeurs sont comprises entre 1 et
; The bigger values, the slower. | 255. Plus elles sont grandes, plus
; | c'est lent.
Gauges_scrolling_speed_Left = 10 ; (default 10)
Gauges_scrolling_speed_Right = 3 ; (default 3)
 
; Automatically save the configu- | Enregistre automatiquement la configu-
; ration when exiting the program. | ration lorsqu'on quitte le programme.
Auto_save = yes ; (default 'yes')
 
; Maximum number of vertices used | Nombre maximum de vertex utilisés dans
; in filled polygons and polyforms, | les polygônes et polyformes pleins, et
; and lasso. Possible values range | le lasso. Les valeurs possibles vont
; from 2 to 16384. | de 2 à 16384.
; Each vertex takes 4 bytes. | Chaque vertex prend 4 octets.
Vertices_per_polygon = 1024 ; (default 1024)
 
; Automatically zoom into the | Zoomer automatiquement la zone pointée
; pointed area when you press the | par la souris lorsque vous appuyez sur
; short-key of the Magnifier button | la touche de raccourci de la loupe.
; while being above the picture. |
Fast_zoom = yes ; (default 'yes')
 
; Separate the colors in the tool- | Séparer les couleurs dans la barre
; bar by a black squaring. | d'outils par un quadrillage noir.
Separate_colors = no ; (default 'no')
 
; Initial value of the feedback for | Valeur initiale du "feedback" pour les
; the drawing modes (cf. docs). | modes de dessin (cf. docs).
FX_feedback = yes ; (default 'yes')
 
; When you reduce the palette or | Si vous réduisez la palette ou "zappez"
; "zap" some colors out of it, it is| quelques couleurs, il est possible
; possible that there are not enough| qu'il ne reste pas assez de couleurs
; colors left to draw the menus. | pour afficher les menus. Mettre cette
; Switching the following variable | variable à 'yes' ramènera automatiquent
; on will bring back the colors of | les couleurs du menu s'il reste moins
; the menu if there are less than 4 | de 4 couleurs après une "réduction" ou
; colors left after "reducing" or | un "zapping".
; "zapping". |
Safety_colors = yes ; (default 'yes')
 
; Display a message at startup | Afficher un message au démarrage
; telling the version number of the | indiquant le numéro de version du
; program. | programme.
Opening_message = yes ; (default 'yes')
 
; Take the Stencil into account when| Prendre le Stencil en compte lorsqu'on
; clearing the image. | efface l'image.
Clear_with_stencil = yes ; (default 'yes')
 
; Directly set the discontinuous | Passer automatiquement en mode de
; freehand drawing mode after brush | dessin discontinu après la prise d'une
; grabbing. | brosse.
Auto_discontinuous = no ; (default 'no')
 
; Save the screen dimensions in GIF | Sauver les dimensions de l'écran dans
; files. If you want to read these | les fichiers GIF. Si vous voulez lire
; files with Photoshop or Alchemy, | ces fichiers avec Photoshop ou Alchemy,
; and maybe some other programs, you| et peut-être d'autres programmes, vous
; must set this option to 'no'. | devez mettre cette option à 'no'.
Save_screen_size_in_GIF = no ; (default 'no')
 
; Automaticaly count the number of | Compter automatiquement le nombre de
; different colors used when opening| couleurs différentes utilisées lors de
; the palette editor window. (Set it| d'ouverture de la fenêtre d'édition de
; to 'no' if you have a slow PC or | la palette. (Mettez-le à 'no' si vous
; if you edit huge pictures) | avez un PC lent ou bien si vous éditez
; | d'énormes images).
Auto_nb_colors_used = yes ; (default 'yes')
 
; Default video mode at startup | Mode vidéo par défaut au
; (see the list by running the | démarrage (voir la liste en lançant
; program with argument "/?". | le programme avec l'option "/?".
Default_video_mode = window ; (default 'window')
 
; Window dimensions. The program | Dimensions de la fenêtre en mode
; remembers the last window size. | fenêtré.
Default_window_size = 640,480 ; (default '640,480')
 
; This setting allows you merge successive mouse movements into a single
; mouse movement. You should only use it if you are using a mouse which
; reports at 200Hz or more, and you experience lag when using discontinuous
; hand-drawing with large brushes (this tool tries to paste the brush and
; update the screen on each new mouse position) In this case, set this to 2
; or more, to ignore some intermediate mouse reports when a more recent one
; is present.
; Note that with a value superior to 1, you lose precision with continuous
; hand-drawing, as intermediate mouse positions are skipped.
Merge_movement = 0 ; (default 0)
 
; Number of columns in the palette of the menu bar. Can be any number from
; 1 to 256. If there is not enough room, the program will display less
; columns. But your preference will be kept, and as soon as there is more
; space in the screen, more columns will be shown.
;
Palette_Cells_X = 16; (Default 16)
; Number of lines in the palette of the menu. Can be any number from
; 1 to 16. The menu can always display the number of lines you request.
;
Palette_Cells_Y = 4; (Default 4)
 
; Bookmarked directories. Leave the directory blank for unused ones.
;
Bookmark_label =
Bookmark_directory =
 
Bookmark_label =
Bookmark_directory =
 
Bookmark_label =
Bookmark_directory =
 
Bookmark_label =
Bookmark_directory =
 
; In the classic layout, the palette in the menu has colors from left to
; right. If you prefer the colors ordered top to bottom, set this option
; to YES.
;
Palette_vertical = YES; (Default YES)
 
; The program remembers the last window position, if the
; OS isn't able to do it by itself. (ie: Windows)
Window_position = 9999,9999; (Default 9999,9999 which means: NA)
 
; This is the time (in milliseconds) between two clicks for Grafx2 to
; recognize a double-click. Double-click is used mostly in the palette
; area of the menu: double-click a color to open the palette.
Double_click_speed = 500; (Default 500)
 
; When you press two digit keys in rapid succession (ex: 3 8), Grafx2
; sets transparency to 38% (instead of 30% then 80%). This setting
; allows you to set the maximum delay between two keypresses for
; GrafX2 to recognize them as a combo.
Double_key_speed = 500; (Default 500)
 
; Name of the skinfile you want to | Nom du fichier skin que vous voulez
; use. | utiliser.
; Default : (empty to let the program choose)
Skin_file =
 
; Name of the font file (8x8) you | Nom du fichier police de caractère
; want to use. | 8x8 utilisée dans les menus.
; Default : (empty to let the program choose)
Font_file =
 
; This determines the color value for the grid. Each pixel of
; the grid will be displayed by XOR-ing the original color with
; the value of this setting.
; For example, if you always paint 16-color images, you can set it
; to 16 so the color of the grid are 16 for 0, 17 for 1, etc.
; Then you can set colors 16-31 as lighter/darker variants
; of your original palette, resulting in a pretty grid !
;
; Valid values are 1 to 255.
Grid_XOR_color = 255; (Default 255)
 
; This records the last pixel ratio used, to restore it on start.
; Valid values are from 0 to 7 for: Simple, Wide, Tall, Double,
; Triple, Wide2, Tall2, Quadruple.
;
Pixel_ratio = 0; (Default 0)
 
; This records the visibility of toolbars, to restore them on start.
; It's a bitfield, where 1=Status, 2=Layers/Animation, 4=Tools
;
Menubars_visible = 255; (Default 255)
; This enables a mode where right mouse buttons acts as
; a color picker, with most tools.
;
Right_click_colorpick = NO; (Default NO)
 
; When this mode is active, scrolling the view (and the magnifier view)
; affects both the main image and the spare page - as long as they have
; the same dimensions.
;
Sync_views = YES; (Default YES)
; This setting determines which key inverts the mouse buttons
; when it's held : A left click is then interpreted as a right-click.
; It's especially useful for one-button controllers,
; such as touchscreens and tablets.
; Possible values are 0 (none), 1 (control), 2 (alt)
;
Swap_buttons = 1; (Default 1)
; Last directory browsed with the script selector.
; Leave blank to initially start in (data directory)/scripts
;
Scripts_directory =
; When this setting is disabled, and you create a shortcut with a key that
; is already associated to another shortcut, Grafx2 will unset the latter.
; If you enable this mode, Grafx2 will not make such check, so you can design
; shortcuts that trigger several actions at once.
;
Allow_multi_shortcuts = no; (Default no)
; Determines if the Tilemap tool should identify tiles that are mirrored
; version of other tiles, on the X axis.
;
Tilemap_detect_mirrored_x = no; (Default no)
 
; Determines if the Tilemap tool should identify tiles that are mirrored
; version of other tiles, on the Y axis.
;
Tilemap_detect_mirrored_y = no; (Default no)
; Determines if the Tilemap tool should identify tiles that are reversed
; versions of other tiles (180°).
;
Tilemap_detect_mirrored_xy = no; (Default no)
 
; Determines if the Tilemap tool should show the number of distinct tiles
; at the end of analysis.
;
Tilemap_count = no; (Default no)
 
; Enables the virtual keyboard when the user enters a textbox.
;
; 0=Auto (guess), 1=ON, 2=OFF
Use_virtual_keyboard = 0; (Default 0)
; Indicates if new images should by default use layers. The alternative
; is animation frames.
;
Default_mode_layers = no; (Default no)
; end of configuration
/data/common/media/grafx2/grafx2
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/scripts/_tst_AAFilter.lua
0,0 → 1,30
-- Apply a kind of AA filter on picture
 
-- Get the picture size
w, h = getpicturesize();
 
-- Here is the filtering matrix
matrix = {
{ 0, -1, 0 },
{ -1, 5, -1 },
{ 0, -1, 0 }};
 
-- Loop trough all the pixels
-- To make this script simpler we don't handle the picture borders
-- (the matrix would get pixels outside the picture space)
-- for var = start_value, end_value, step do ...
for y = 1, h - 2, 1 do
for x = 1, w - 2, 1 do
filtered =
matrix[1][1] * getbackuppixel(x - 1, y - 1) +
matrix[1][2] * getbackuppixel(x , y - 1) +
matrix[1][3] * getbackuppixel(x + 1, y - 1) +
matrix[2][1] * getbackuppixel(x - 1, y ) +
matrix[2][2] * getbackuppixel(x , y ) +
matrix[2][3] * getbackuppixel(x + 1, y ) +
matrix[3][1] * getbackuppixel(x - 1, y + 1) +
matrix[3][2] * getbackuppixel(x , y + 1) +
matrix[3][3] * getbackuppixel(x + 1, y + 1);
putpicturepixel(x,y,filtered);
end
end
/data/common/media/grafx2/scripts/_tst_GradientBrush.lua
0,0 → 1,7
w, h = getbrushsize()
 
for x = 0, w - 1, 1 do
for y = 0, h - 1, 1 do
putbrushpixel(x, y, (x+y)%256);
end
end
/data/common/media/grafx2/scripts/_tst_Settings.lua
0,0 → 1,33
-- Test LUA inputbox
-- this script tests the inputbox
 
w, h = getbrushsize()
--[[
messagebox(
"Forecolor: " .. getforecolor() .. "\n" ..
"Backcolor: " .. getbackcolor() .. "\n" ..
"Transparent color: " .. gettranscolor() .. "\n" ..
"Brush dimensions: " .. w .. "x" .. h
)
]]
 
 
ok, w, h = inputbox("Modify brush",
"RGB", 1, 0, 1, -1,
"HSV", 0, 0, 1, -1,
"HSL", 0, 0, 1, -1,
"Width", w, -900.0,900.0, 3,
"Height", h, -900.0,900.0, 4,
"X Flip", 0, 0, 1, 0,
"Y Flip", 0, 0, 1, 0,
"Degrees",1, 0, 1, -2,
"Radians",0, 0, 1, -2
);
if ok == true then
messagebox(
"w: " .. w .. "\n" ..
"h: " .. h .. "\n"
)
end
 
 
/data/common/media/grafx2/scripts/_tst_dialog.lua
0,0 → 1,66
local counter=0;
local printcounter = function ()
windowprint(10,54, string.format("% .3d", counter));
end;
 
windowopen(100,150, "Dialogtest");
windowbutton(6, 18, 54, 14, "Close", 27); -- 1, shortcut=ESC
windowrepeatbutton(6, 38, 14, 14, "+"); -- 2
windowrepeatbutton(26, 38, 14, 14, "-"); -- 3
windowbutton(6, 70, 54, 14, "Help"); -- 4
windowinput(6, 88, 10);
printcounter();
 
repeat
local button, button2, key = windowdodialog();
 
if button == 2 then -- "+"
counter=counter+1;
printcounter();
end
if button == 3 then -- "-"
counter=counter-1;
printcounter();
end
if button == 4 then -- "Help"
messagebox("Help screen");
end
until key == 27 or button == 1;
windowclose();
 
 
-- messagebox(tostring(button) .. " " .. tostring(button2));
 
 
---- Open_window(149,118,"Grid");
-- Display_cursor();
-- Hide_cursor();
---- Close_window();
---- Update_window_area(0,0,Window_width, Window_height);
---- clicked_button=Window_clicked_button();
--
-- -- standard button
---- Window_set_normal_button(12,92,51,14,"Cancel",0,1,KEY_ESC); -- 1
-- -- repeatable button (while held)
---- Window_set_repeatable_button(202,43,13,11,"-",0,1,SDLK_LAST); -- 8
-- -- text input
-- Window_set_input_button(29,24,3); -- 3
-- Window_input_content(input_x_button,str);
-- Readline(31,26,str,3,INPUT_TYPE_INTEGER);
--
-- -- dropdown
-- Window_set_dropdown_button(216, 158, 84,14,84,"Preset...", 0,0,1,RIGHT_SIDE|LEFT_SIDE,1);
-- Window_dropdown_clear_items(Button);
-- Window_dropdown_add_item(Button,0,"Set");
--
-- -- vertical scroller
-- mix_scroller = Window_set_scroller_button(31,20,84,256,1,Main_backups->Pages->Gradients->Range[Current_gradient].Mix);
-- Window_draw_slider(mix_scroller);
--
-- -- display
---- Print_in_window(11,26, "X:",MC_Dark,MC_Light);
---- Print_in_window_limited(Button->Pos_X+3+10,Button->Pos_Y+2,Config.Bookmark_label[bookmark_number],8,MC_Black,MC_Light);
-- Window_display_frame_in( 6, 21,110, 52);
-- Window_display_frame(6,17,130,37);
-- Window_rectangle(panel->Pos_X, panel->Pos_Y, panel->Width, panel->Height+1, MC_Light);
 
/data/common/media/grafx2/scripts/_tst_dialog2.lua
0,0 → 1,33
--
-- test of GUI library
--
run("libs/gui.lua")
 
local counter = gui.label{x=10, y=54, value=0, format="% .3d"}
local form = gui.dialog{
title="Dialogtest",
w=100,
h=150,
counter,
gui.button{ label="+",
x=6, y=38, w=14, h=14, repeatable=true, click=function()
counter.value=counter.value+1;
counter:render();
end},
gui.button{ label="-",
x=26, y=38, w=14, h=14, repeatable=true, click=function()
counter.value=counter.value-1;
counter:render();
end},
gui.button{ label="Help",
x=6, y=70, w=54, h=14, click=function()
messagebox("Help screen");
end},
gui.button{ label="Close",
x=6, y=18, w=54, h=14, key=27, click=function()
return true; -- causes closing
end},
}
 
form:run()
 
/data/common/media/grafx2/scripts/libs/gui.lua
0,0 → 1,111
--
-- Event-driven GUI library
--
--
 
gui = {
 
--
-- dialog() --
--
dialog = function(args)
local dia = {
title = args.title,
w = args.w,
h = args.h,
--
widgets = {},
-- an indexed array, starting at 1. Used for calling the relevant
-- callback when a numbered control is clicked.
callbacks = {},
--
-- dialog.run() --
--
run = function(this)
windowopen(this.w,this.h, this.title or "");
-- examine all elements
for _,widget in ipairs(this.widgets) do
widget:render()
end
repeat
local button, button2, key = windowdodialog();
if button > 0 then
local c = this.callbacks[button]
-- run the callback and stop the form if it returns true
if c ~= nil and c(this) then
break;
end
end
until key == 27;
windowclose();
end
}
local id = 1;
-- examine all elements
for _,value in ipairs(args) do
-- all arguments that are tables are assumed to be widgets
if type(value)=="table" then
table.insert(dia.widgets, value)
-- clickable widgets take up an auto-numbered id
if (value.click) then
dia.callbacks[id] = value.click
id=id+1
end
end
end
return dia;
end,
 
--
-- button() --
--
button = function(args)
local but = {
x = args.x,
y = args.y,
w = args.w,
h = args.h,
key = args.key,
label = args.label,
click = args.click or donothing,
render = args.repeatable and function(this)
windowrepeatbutton(this.x, this.y, this.w, this.h, this.label, this.key or -1);
end
or function(this)
windowbutton(this.x, this.y, this.w, this.h, this.label, this.key or -1);
end
}
return but;
end,
 
--
-- label() --
--
label = function(args)
local fld = {
x = args.x,
y = args.y,
value = args.value,
format = args.format,
fg = args.fg or 0,
bg = args.bg or 2,
render = function(this)
if type(this.format) then
windowprint(this.x, this.y, string.format(this.format, this.value), this.fg, this.bg);
else
windowprint(this.x, this.y, this.value, this.fg, this.bg);
end
end
}
return fld;
end,
 
 
-- "do nothing" function. Used as default callback
donothing = function(this)
end
 
}
/data/common/media/grafx2/scripts/samples_2.4/brush/ApplyColor.lua
0,0 → 1,129
--BRUSH Remap: Apply PenColor
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
run("../libs/dawnbringer_lib.lua")
 
OK,tin,clz,fade,amt,brikeep,falloff,nobg,nopen,briweight = inputbox("Apply PenColor 2 Brush",
"1. Tint", 1, 0,1,-1,
"2. Colorize", 0, 0,1,-1,
"BG->FG color Fade", 0, 0,1,0,
"AMOUNT % (0-100)", 100, 0,100,0,
"Preserve Brightness", 1, 0,1,0,
"Bri/Dark FallOff", 1, 0,1,0,
"Exclude Background", 1,0,1,0,
"Exclude PenColor", 0,0,1,0,
"ColMatch Bri-Weight %", 25, 0,100,0
);
 
 
if OK == true then
 
function cap(v) return math.min(255,math.max(v,0)); end
 
w, h = getbrushsize()
 
 
fg = getforecolor()
bg = getbackcolor()
fR,fG,fB = getcolor(fg)
bR,bG,bB = getcolor(bg)
 
pal = db.fixPalette(db.makePalList(256))
if nobg == 1 then
pal = db.stripIndexFromPalList(pal,bg) -- Remove background color from pallist
end
if nopen == 1 then
pal = db.stripIndexFromPalList(pal,fg) -- Remove Pencolor from pallist
end
 
 
amtA = amt / 100
amtR = 1 - amtA
 
-- Normalize Pen Color
lev = (fR+fG+fB)/3
fR = fR - lev
fG = fG - lev
fB = fB - lev
 
---------------------------------------------------
-- Colorize (Colourant) (just apply colorbalance)
-- Tint (make grayscale and apply colorbalance)
--
-- I think it should be the other way around since colorize is the process of adding color to B&W film...
-- But this is the what Brilliance and others call it
--
if clz == 1 or tin == 1 then
cols = {}
for n = 0, 255, 1 do
 
r,g,b = getcolor(n)
a = db.getBrightness(r,g,b)
 
mR,mG,mB = fR,fG,fB
 
-- Fade between bg & fg pencolor across dark-bright
if fade == 1 then
lf = a / 255
lr = 1 - lf
mR = bR*lr + fR*lf
mG = bG*lr + fG*lf
mB = bB*lr + fB*lf
lev = (mR+mG+mB)/3
mR = mR - lev
mG = mG - lev
mB = mB - lev
end
 
fr,fg,fb = mR,mG,mB
 
if brikeep == 1 then
-- Loose Brightness preservation (ex: applying full red to dark colors)
brin = db.getBrightness(cap(r+mR),cap(g+mG),cap(b+mB))
itot = brin - a
fr = mR - itot
fg = mG - itot
fb = mB - itot
end
 
-- Falloff (Effect weakens at dark and bright colors)
if falloff == 1 then
fo = 1 - math.abs((a - 127.5)/127.5)^2
fr = fr * fo
fg = fg * fo
fb = fb * fo
end
 
if tin == 1 then
--cols[n+1] = matchcolor((a+fr)*amtA + r*amtR, (a+fg)*amtA + g*amtR, (a+fb)*amtA + b*amtR)
cols[n+1] = db.getBestPalMatchHYBRID({(a+fr)*amtA+r*amtR, (a+fg)*amtA + g*amtR, (a+fb)*amtA + b*amtR},pal,briweight / 100,true)
end
if clz == 1 then
--cols[n+1] = matchcolor((r+fr)*amtA + r*amtR, (g+fg)*amtA + g*amtR, (b+fb)*amtA + b*amtR)
cols[n+1] = db.getBestPalMatchHYBRID({(r+fr)*amtA+r*amtR, (g+fg)*amtA + g*amtR, (b+fb)*amtA + b*amtR},pal,briweight / 100,true)
end
end
 
if nobg == 1 then cols[getbackcolor()+1] = getbackcolor(); end
 
for x = 0, w - 1, 1 do
for y = 0, h - 1, 1 do
putbrushpixel(x, y, cols[getbrushpixel(x,y) + 1]);
end
end
end;
-- eof Colorize & Tint
--------------------------------------------------------
 
end -- OK
/data/common/media/grafx2/scripts/samples_2.4/brush/Fisheye.lua
0,0 → 1,31
--BRUSH Distortion: FishEye
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
--http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
w, h = getbrushsize()
 
 
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
 
ox = x / w;
oy = y / h;
v = (math.cos((ox-0.5)*math.pi)*math.cos((oy-0.5)*math.pi))*0.85;
ox = (1 + ox - (ox-0.5)*v) % 1;
oy = (1 + oy - (oy-0.5)*v) % 1;
c = getbrushbackuppixel(math.floor(ox*w),math.floor(oy*h));
putbrushpixel(x, y, c);
end
end
 
/data/common/media/grafx2/scripts/samples_2.4/brush/GrayscaleAvg.lua
0,0 → 1,24
--BRUSH Remap: Grayscale (average)
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
w, h = getbrushsize()
 
for x = 0, w - 1, 1 do
for y = 0, h - 1, 1 do
r, g, b = getcolor(getbrushpixel(x,y))
 
a = (r+g+b)/3
 
putbrushpixel(x, y, matchcolor(a,a,a));
 
end
end
/data/common/media/grafx2/scripts/samples_2.4/brush/GrayscaleDesat.lua
0,0 → 1,36
--BRUSH Remap: Grayscale (desaturate)
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
--http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
 
percent = 100
 
--
function desaturate(percent,r,g,b) -- V1.0 by Richard Fhager
p = percent / 100
a = (math.min(math.max(r,g,b),255) + math.max(math.min(r,g,b),0)) * 0.5 * p
r = r + (a-r*p)
g = g + (a-g*p)
b = b + (a-b*p)
return r,g,b
end
--
 
 
w, h = getbrushsize()
 
for x = 0, w - 1, 1 do
for y = 0, h - 1, 1 do
putbrushpixel(x, y, matchcolor(desaturate(percent,getcolor(getbrushpixel(x,y)))));
end
end
/data/common/media/grafx2/scripts/samples_2.4/brush/Halfsmooth.lua
0,0 → 1,34
--BRUSH: Halfsize with smoothscaling
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
w, h = getbrushsize()
 
setbrushsize(math.floor(w/2),math.floor(h/2))
 
for x = 0, w - 1, 2 do
for y = 0, h - 1, 2 do
r1,g1,b1 = getcolor(getbrushbackuppixel(x,y));
r2,g2,b2 = getcolor(getbrushbackuppixel(x+1,y));
r3,g3,b3 = getcolor(getbrushbackuppixel(x,y+1));
r4,g4,b4 = getcolor(getbrushbackuppixel(x+1,y+1));
r = (r1 + r2 + r3 + r4 ) / 4;
g = (g1 + g2 + g3 + g4 ) / 4;
b = (b1 + b2 + b3 + b4 ) / 4;
c = matchcolor(r,g,b);
 
putbrushpixel(x/2, y/2, c);
 
end
end
 
 
/data/common/media/grafx2/scripts/samples_2.4/brush/Waves.lua
0,0 → 1,42
--BRUSH Distortion: Waves v1.0
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
-- http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
 
--frq = 2
--amp = 0.3
 
-- Adjust power of frequency & amplitude
frq_adj = 2
amp_adj = 0.02
 
ok,frq,amp = inputbox("Settings",
"Frequency 1-10", 3, 1,10,0,
"Amplitude 1-10", 3, 1,10,0
);
 
w, h = getbrushsize()
 
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
 
ox = x / w;
oy = y / h;
ox = (1 + ox + math.sin(oy*math.pi*frq*frq_adj)*amp*amp_adj) % 1;
c = getbrushbackuppixel(math.floor(ox*w),y);
putbrushpixel(x, y, c);
 
end
end
 
/data/common/media/grafx2/scripts/samples_2.4/codenetsend.lua
0,0 → 1,17
-- Codenet send for grafx2 2.4 and up, by Michael Ilsaas.
-- Sends the latest saved picture. Set the IP address of the C64 in the line below.
ip = "192.168.0.64"; -- <-- IP address of the C64.
fn, fp = getfilename();
picfile = assert(io.open(fp .. '/' .. fn ,"r"));
picsize = picfile:seek("end")
picfile:close();
if picsize == 9000 or picsize == 9002 then -- check for hires
os.execute("echo AQgLCAoAnjIwNjIAAAAArQDdKfwJAo0A3ak4jRjQqQiNFtCpO40R0KkAjSDQogC9DA6dAGC9DA+dAGG9DBCdAGK9DBGdAGO9DBKdAGS9DBOdAGW9DBSdAGa9DBWdAGe9DBadAGi9DBedAGm9DBidAGq9DBmdAGu9DBqdAGy9DBudAG29DBydAG69DB2dAG/o4ADQm6IAvQwenQBwvQwfnQBxvQwgnQByvQwhnQBzvQwinQB0vQwjnQB1vQwknQB2vQwlnQB3vQwmnQB4vQwnnQB5vQwonQB6vQwpnQB7vQwqnQB8vQwrnQB9vQwsnQB+vQwtnQB/6OAA0JuiAL1MLZ0ATL1MLp0ATb1ML50ATr1MMJ0AT+jgANDjvUUJnQDAvUUKnQDBvUULnQDCvUUMnQDDvUUNnQDEvUUOnQDF6OAA0NdMAMCpwI00A6mojTUDqQCNNgOpQI03A60B3gkBjQHeor+gxCBbwxAJqQagwqkITLnESKkYoMJoqQ14IP7DEPtYIOH/0ANMucR4IP7DMPGtRAPJCNDqrUUD8ArJBtDhIA/DTDzArUYDyUXQ1K1MAym/DU0D0MqtTwPJEfA2yQHwCKkCIKzCTDzArVoDyQjQIKkAjVoDGK1cA2kIjVwDkAruXQPQBe5cA/D2IDjCIJnCTDzArVwDyRnQB61dA8k+8AipAyCswkw8wK1iA8nK0OCtYwPJH9DZrWUDSKkBjWUDqQCNSAONXgONYAOF+oX7qSCNSQOpGI1fA6kRjWEDrVoDrlwDjloDjVwDrVsDrl0DjlsDjV0DGKISpft9UwOF+6X6fVIDhfrKyhDukAjm+9AE5vrw+KX6Sf+NYAOl+0n/jWEDTl8DIDjCIJnCrWYDhf2tZwOF/K5oA6xpA2jJBPAPyQXwPskG8GvJB/B6TDzAziDQpQFIKfgJA4UBrmkDoAC5agOR/MjK0PdohQHuINAYmGX8ha6FLaX9aQCFr4UuTDzAqTOFAZhIivASrWoDoACR/MiR/MjQ+Ob9ytDzaKrwC61qA6AAkfzIytD6qTeFAUw8wKX80ALG/cb8pf1IpfxIqQhMucSiCL35wZ1AA8oQ96kDSKk/SKkITLnEIFmmIDOlTK6nQkNERk5PIFJSLU5FVCBGT1VORC4NAFJSLU5FVCBGT1VORC4gQ1M4OTAwQSBSRVZJU0lPTiAAogO9UgOdVgO9NAOdUgPKEPGpgI1OA6kAjVADjVEDhfqF+xiiEqX7fUcDhful+n1GA4X6ysoQ7pAI5vvQBOb68Pil+kn/jVADpftJ/41RA6IFvT4DnTgDvb/EnT4DyhDxYBitSQNpDqqtSANpANAEikxpxGBIohy9RgOdXgPKEPeiB6kAnVoDytD6hfqF+41IA6k0jUkDqQGNTwOpA41aA2iNWwMYoh6l+31bA4X7pfp9WgOF+srKEO6QCOb70ATm+vD4pfpJ/41cA6X7Sf+NXQMgOMJMmcKiB71Tw91GA9A5yhD1ogO9NAPdXgPQLMoQ9akCjU0Dogm9TgOdWAO9v8SdTgPKEPGiA700A51UA8oQ9yCHwqk8TGnEYAABCAAGBAABhvyE/SC5wxABYEip/4X6oACYSBhprCDtw4ol+oX6mCX6hfpoqMjAA9DnpfrJ/9AaoACx/KrImEix/KhoSEoJrCDcw2ioyMAG0OipgqIFoA8g3MOpiaLToAAg3MNoYKkAIO3D4A7QF8Bj0BOpASDtw4rQC8ALsAeYOOkHkAFgqf9gCo0C3qkAKo0D3o4E3owF3mAKjQLeqQAqjQPergTerAXeYKmSIO3DmCl/0AOp/2CtCd6tCN6sCd6uCN6Y0CngyLAlikoIqvAToACtCN6ZOAPIrQnemTgDyMrQ7yiQBq0I3pk4A6kAYIpImPAOogCtCN6tCd7o0PeI0PRoqvAMrQjeyvAGrQneytD0qf9gosmODN6iAI4N3o0O3o4P3kipkiDtw5gpf/ASrQnerQjerAnergjeIEPETHrEqZwg7cOYKQHw2mhKaQCqoAC5OAONCN7IuTgDjQneyMrQ72CpAI0g0GAAgBCxMhg= | base64 -d > /tmp/picview.prg");
else
os.execute("echo AQgLCAoAnjIwNjIAAAAArQDdKfwJAo0A3ak4jRjQqRiNFtCpO40R0K0/NY0h0KkAjSDQogC9Lw6dAGC9Lw+dAGG9LxCdAGK9LxGdAGO9LxKdAGS9LxOdAGW9LxSdAGa9LxWdAGe9LxadAGi9LxedAGm9LxidAGq9LxmdAGu9LxqdAGy9LxudAG29LxydAG69Lx2dAG/o4ADQm6IAvS8enQBwvS8fnQBxvS8gnQByvS8hnQBzvS8inQB0vS8jnQB1vS8knQB2vS8lnQB3vS8mnQB4vS8nnQB5vS8onQB6vS8pnQB7vS8qnQB8vS8rnQB9vS8snQB+vS8tnQB/6OAA0JuiAL1vLZ0ATL1vLp0ATb1vL50ATr1vMJ0AT+jgANDjvVcxnQDYvVcynQDZvVcznQDavVc0nQDb6OAA0OO9aAmdAMC9aAqdAMG9aAudAMK9aAydAMO9aA2dAMS9aA6dAMXo4ADQ10wAwKnAjTQDqaiNNQOpAI02A6lAjTcDrQHeCQGNAd6iv6DEIFvDEAmpBqDCqQhMucRIqRigwmipDXgg/sMQ+1gg4f/QA0y5xHgg/sMw8a1EA8kI0OqtRQPwCskG0OEgD8NMPMCtRgPJRdDUrUwDKb8NTQPQyq1PA8kR8DbJAfAIqQIgrMJMPMCtWgPJCNAgqQCNWgMYrVwDaQiNXAOQCu5dA9AF7lwD8PYgOMIgmcJMPMCtXAPJGdAHrV0DyT7wCKkDIKzCTDzArWIDycrQ4K1jA8kf0NmtZQNIqQGNZQOpAI1IA41eA41gA4X6hfupII1JA6kYjV8DqRGNYQOtWgOuXAOOWgONXAOtWwOuXQOOWwONXQMYohKl+31TA4X7pfp9UgOF+srKEO6QCOb70ATm+vD4pfpJ/41gA6X7Sf+NYQNOXwMgOMIgmcKtZgOF/a1nA4X8rmgDrGkDaMkE8A/JBfA+yQbwa8kH8HpMPMDOINClAUgp+AkDhQGuaQOgALlqA5H8yMrQ92iFAe4g0BiYZfyFroUtpf1pAIWvhS5MPMCpM4UBmEiK8BKtagOgAJH8yJH8yND45v3K0PNoqvALrWoDoACR/MjK0PqpN4UBTDzApfzQAsb9xvyl/Uil/EipCEy5xKIIvfnBnUADyhD3qQNIqT9IqQhMucQgWaYgM6VMrqdCQ0RGTk8gUlItTkVUIEZPVU5ELg0AUlItTkVUIEZPVU5ELiBDUzg5MDBBIFJFVklTSU9OIACiA71SA51WA700A51SA8oQ8amAjU4DqQCNUAONUQOF+oX7GKISpft9RwOF+6X6fUYDhfrKyhDukAjm+9AE5vrw+KX6Sf+NUAOl+0n/jVEDogW9PgOdOAO9v8SdPgPKEPFgGK1JA2kOqq1IA2kA0ASKTGnEYEiiHL1GA51eA8oQ96IHqQCdWgPK0PqF+oX7jUgDqTSNSQOpAY1PA6kDjVoDaI1bAxiiHqX7fVsDhful+n1aA4X6ysoQ7pAI5vvQBOb68Pil+kn/jVwDpftJ/41dAyA4wkyZwqIHvVPD3UYD0DnKEPWiA700A91eA9AsyhD1qQKNTQOiCb1OA51YA72/xJ1OA8oQ8aIDvTQDnVQDyhD3IIfCqTxMacRgAAEIAAYEAAGG/IT9ILnDEAFgSKn/hfqgAJhIGGmsIO3DiiX6hfqYJfqF+mioyMAD0Oel+sn/0BqgALH8qsiYSLH8qGhISgmsINzDaKjIwAbQ6KmCogWgDyDcw6mJotOgACDcw2hgqQAg7cPgDtAXwGPQE6kBIO3DitALwAuwB5g46QeQAWCp/2AKjQLeqQAqjQPejgTejAXeYAqNAt6pACqNA96uBN6sBd5gqZIg7cOYKX/QA6n/YK0J3q0I3qwJ3q4I3pjQKeDIsCWKSgiq8BOgAK0I3pk4A8itCd6ZOAPIytDvKJAGrQjemTgDqQBgikiY8A6iAK0I3q0J3ujQ94jQ9Giq8AytCN7K8AatCd7K0PSp/2CiyY4M3qIAjg3ejQ7ejg/eSKmSIO3DmCl/8BKtCd6tCN6sCd6uCN4gQ8RMesSpnCDtw5gpAfDaaEppAKqgALk4A40I3si5OAONCd7IytDvYKkAjSDQYACAELEyGA== | base64 -d > /tmp/picview.prg");
end
if picsize == 9000 or picsize == 10001 then -- check for loadaddress, add two bytes if not found
os.execute('echo a >> /tmp/picview.prg');
end
os.execute('cat '.. fp .. '/' .. fn .. ' >> /tmp/picview.prg'); -- append pic to c64 binary
os.execute("codenet -x /tmp/picview.prg -n "..ip); -- send file to c64
/data/common/media/grafx2/scripts/samples_2.4/demo/3DPalette.lua
0,0 → 1,460
--3D-Palette viewer V0.72 (HSL-models added, 3D-World added, Pen-color only cycles thru unique colors, InputBox)
--by Richard 'Dawnbringer' Fhager
 
-- Mouse: Rotate Cube (Stops animation)
-- Arrow-keys: Move Cube (in 3D world)
-- F1: Start/Stop animation
-- F2: Reset
-- F3: Increase Color-Size
-- F4: Decrease Color-Size
-- F5: (Wip) Cycle thru selected PenColor (Note that only unique colors are displayed)
-- F9: RGB-space model
--F10: HSL-space model
--F11: HSLcubic-space model
-- "+" (Num): Zoom In
-- "-" (Num): Zoom Out
-- Esc: Exit script
 
-- Drawing updated, rectangle missing, Sep11
 
run("../libs/dawnbringer_lib.lua")
 
 
BRIDIAG_SHOW = 1 -- Show brightness/Grayscale diagonal (1 = on, 0 = off)
ANIM = 1 -- Animation (1 = on, 0 = off)
BOX_DRK = 8 -- Darkest color used for box (0-255)
BOX_BRI = 112 -- Brightest color used for box (0-255)
COLSIZE_BASE = 26 -- Colors base size (value to adjusted by palette-size, with 2 cols maxsize is v / 1.23)
 
--
OK,RGB,HSL,HSLC,BOX_BRI,COLSIZE_BASE,SET800x600 = inputbox("3D-Palette Viewer Settings",
"1. RGB space [F9]", 1, 0,1,-1,
"2. HSL space [F10]", 0, 0,1,-1,
"3. HSL-cubic space [F11]",0, 0,1,-1,
"Box Brightness (16-255)", BOX_BRI, 16,255,0,
"Col Size (1-100) [F3/F4]", COLSIZE_BASE, 1,100,0,
"Set Screen to 800x600", 1,0,1,0
);
--
 
if OK then
 
if SET800x600 == 1 then setpicturesize(800,600); end
 
SPACE = "rgb"
FORM = "cube"
if HSL == 1 then
SPACE = "hsl"
FORM = "cylinder"
end
if HSLC == 1 then
SPACE = "hsl_cubic"
FORM = "cube"
end
 
 
pal = db.fixPalette(db.makePalList(256))
 
FG = getforecolor()
BG = getbackcolor()
 
palcol = FG
 
--
function initColors(space)
for n = 1, #pal, 1 do
c = pal[n];
if space == "rgb" then
cols[n] = {c[1]/128-1,c[2]/128-1,c[3]/128-1,c[4]};
end
if space == "hsl_cubic" then
cols[n] = {}
cols[n][1] = (db.getHUE(c[1],c[2],c[3],0) / 6.0 * 255) / 128 - 1
cols[n][2] = (db.getSaturation(c[1],c[2],c[3])) / 128 - 1
cols[n][3] = (db.getLightness(c[1],c[2],c[3])) / 128 - 1
cols[n][4] = c[4]
end
if space == "hsl" then
cols[n] = {}
hue = db.getHUE(c[1],c[2],c[3],0) / 6.0 * math.pi*2
rad = db.getSaturation(c[1],c[2],c[3]) / 256
cols[n][1] = math.cos(hue) * rad
cols[n][2] = math.sin(hue) * rad
cols[n][3] = (db.getLightness(c[1],c[2],c[3])) / 128 - 1
cols[n][4] = c[4]
end
end
end
--
 
cols = {} -- Make points of palette colors
colz = {} -- To hold calculated points
initColors(SPACE)
 
 
function initPointsAndLines(form,bridiag)
if form == "cube" then
pts = {{-1,1,-1},{1,1,-1},{1,-1,-1},{-1,-1,-1}, -- The box
{-1,1, 1},{1,1, 1},{1,-1, 1},{-1,-1, 1}}
lin = {{1,2},{2,3},{3,4},{4,1},{5,6},{6,7},{7,8},{8,5},{1,5},{2,6},{3,7},{4,8}} -- Box Lines
if bridiag == 1 then lin[13] = {4,6}; end
end
if form == "cylinder" then
p = 28
pts = {}
lin = {}
for n = 1, p, 1 do
x = math.cos(math.pi*2 / p * (n-1))
y = math.sin(math.pi*2 / p * (n-1))
pts[n] = {x,y,-1}
lin[n] = {n,1 + (n%p)}
pts[n + p] = {x,y,1}
lin[n + p] = {n+p,p + 1 + (n%p)}
end
lin[p*2+1] = {1,p+1} -- Red (0 degrees)
lin[p*2+2] = {p+1,p+1+math.ceil(p/2)} -- Lightness end (needs an even # of points to work)
end
end
 
boxp = {} -- To hold the calculated points
initPointsAndLines(FORM,BRIDIAG_SHOW)
 
w,h = getpicturesize()
CX,CY = w/2, h/2
 
 
 
function initAndReset()
XANG, YANG, ZANG, ZOOM, COLSIZE_ADJ, XD, YD, WORLD_X, WORLD_Y, ZSELECT = 0,0,0,0,0,0,0,0,0,0
end
 
initAndReset()
 
SIZE = math.min(w,h)/4
DIST = 5 -- Distance perspective modifier, ~5 is nominal, more means "less 3D"
 
CMAXSIZE = math.floor(COLSIZE_BASE / ((#pal)^0.3))
--CMAXSIZE = 8
CMINSIZE = 1 -- Negative values are ok. Color are never smaller than 1 pix
 
BOX_LINE_DIV = 20 -- Number of colors/segments that a box-line can be divided into (depth)
BOX_DIV_MULT = BOX_LINE_DIV / (math.sqrt(3)*2)
 
-- Box depth colors
box_div = {}
for n = 0, BOX_LINE_DIV-1, 1 do
c = BOX_DRK + (BOX_BRI / (BOX_LINE_DIV - 1)) * n
--box_div[BOX_LINE_DIV - n] = matchcolor(c,c,c)
box_div[BOX_LINE_DIV - n] = db.getBestPalMatchHYBRID({c,c,c},pal,0.5,true)
end
 
--BOX_COL = matchcolor(80,80,80)
BKG_COL = matchcolor(0,0,0)
--CUR_COL = matchcolor(112,112,112)
 
 
function rotate3D(x,y,z,Xsin,Ysin,Zsin,Xcos,Ycos,Zcos) -- PrecCalced cos&sin for speed
 
local x1,x2,x3,y1,y2,y3,f,xp,yp
 
x1 = x
y1 = y * Xcos + z * Xsin
z1 = z * Xcos - y * Xsin
 
x2 = x1 * Ycos - z1 * Ysin
y2 = y1
z2 = x1 * Ysin + z1 * Ycos
 
x3 = x2 * Zcos - y2 * Zsin
y3 = x2 * Zsin + y2 * Zcos
z3 = z2
 
return x3,y3,z3
end
 
function do3D(x,y,z,zoom,dist,Xsin,Ysin,Zsin,Xcos,Ycos,Zcos) -- PrecCalced cos&sin for speed
 
local x1,x2,x3,y1,y2,y3,f,xp,yp
 
x1 = x
y1 = y * Xcos + z * Xsin
z1 = z * Xcos - y * Xsin
 
x2 = x1 * Ycos - z1 * Ysin
y2 = y1
z2 = x1 * Ysin + z1 * Ycos
 
x3 = x2 * Zcos - y2 * Zsin
y3 = x2 * Zsin + y2 * Zcos
z3 = z2
 
f = dist/(z3 + dist + zoom)
xp = x3 * f
yp = y3 * f
 
return xp,yp,z3
end
 
 
function draw3Dline(x1,y1,z1,x2,y2,z2,div,mult,depthlist)
local s,xt,yt,xd,yd,zd,xf,yf
xd = (x2 - x1) / div
yd = (y2 - y1) / div
zd = (z2 - z1) / div
xf,yf = x1,y1
 
for s = 1, div, 1 do
-- Depth assumes a 1-Box (z ranges from -sq(3) to sq(3))
depth = math.floor(1 + (z1+zd*s + 1.732) * mult)
xt = x1 + xd*s -- + math.random()*8
yt = y1 + yd*s -- + math.random()*8
c = depthlist[depth]
if c == null then c = 1; end -- Something isn't perfect, error is super rare but this controls it
--db.line(xf,yf,xt,yt,c)
drawline(xf,yf,xt,yt,c)
xf = xt
yf = yt
end
end
 
function killinertia()
XD = 0
YD = 0
end
 
-- If using 1-box, z is -sq(3) to sq(3)
minz = math.sqrt(3)
totz = minz * 2
maxrad = CMAXSIZE - CMINSIZE
 
--q = 0
--delay = 4
--move = 0.03
 
while 1 < 2 do
 
-- Time-for-space-wiggle...or somekindof attempt
--WORLD_X = -move
--q = (q + 1) % delay
--if q < delay/2 then WORLD_X = move; end
 
clearpicture(BKG_COL)
 
Xsin = math.sin(XANG); Xcos = math.cos(XANG)
Ysin = math.sin(YANG); Ycos = math.cos(YANG)
Zsin = math.sin(ZANG); Zcos = math.cos(ZANG)
 
-- Rotate Box points
for n = 1, #pts, 1 do
p = pts[n]
x,y,z = p[1],p[2],p[3]
XP,YP,zp = rotate3D(x,y,z,Xsin,Ysin,Zsin,Xcos,Ycos,Zcos)
boxp[n] = {XP,YP,zp}
end
 
-- Rotate Colors in palette
for n = 1, #cols, 1 do
p = cols[n]
x,y,z,c = p[1],p[2],p[3],p[4]
XP,YP,zp = rotate3D(x,y,z,Xsin,Ysin,Zsin,Xcos,Ycos,Zcos)
colz[n] = {XP,YP,zp,c}
end
 
------------------------------------
-- Control world
------------------------------------
 
-- Calculate points anew
 
-- Worldize Box points
for n = 1, #boxp, 1 do
s = SIZE
v = boxp[n]
x = v[1] + WORLD_X
y = v[2] + WORLD_Y
z = v[3]
f = DIST/(z + DIST + ZOOM)
XP = CX + x * f * s
YP = CY + y * f * s
boxp[n] = {XP,YP,z}
end
 
-- Worldize Colors in palette
for n = 1, #colz, 1 do
s = SIZE
v = colz[n]
x = v[1] + WORLD_X
y = v[2] + WORLD_Y
z = v[3]
c = v[4]
f = DIST/(z + DIST + ZOOM)
XP = CX + x * f * s
YP = CY + y * f * s
colz[n] = {XP,YP,z,c}
end
 
 
-------------------------------------
-------------------------------------
 
-- Brightness Diagonal
--if BRIDIAG_SHOW == 1 then
-- p1 = boxp[4]
-- p2 = boxp[6]
-- x1,y1,z1 = p1[1],p1[2],p1[3]
-- x2,y2,z2 = p2[1],p2[2],p2[3]
-- draw3Dline(x1,y1,z1,x2,y2,z2,BOX_LINE_DIV,BOX_DIV_MULT,box_div)
--end
 
--c1 = math.min(FG,BG)
--c2 = math.max(FG,BG)
--p = colz[26]
--XP1,YP1,zp1,c1 = p[1],p[2],p[3],p[4]
--for n = #colz, 1, -1 do
-- p = colz[27]
-- XP2,YP2,zp2,c2 = p[1],p[2],p[3],p[4]
-- drawline(XP1,YP1,XP2,YP2,c1)
--end
 
-- sort on z
db.sorti(colz,3)
 
-- Draw colors
for n = #colz, 1, -1 do
p = colz[n]
XP,YP,zp,c = p[1],p[2],p[3],p[4]
 
radius = CMINSIZE + maxrad - (zp+minz) / totz * maxrad
dorad = math.floor(radius - ZOOM*2 + COLSIZE_ADJ)
 
if dorad >= 1 then
--db.drawCircle(XP,YP,dorad,c)
drawdisk(XP,YP,dorad,c)
--db.drawRectangle(XP,YP,dorad,dorad,c)
else putpicturepixel(XP,YP,c)
end
 
if c == FG or c == BG then
sz = math.max(3,dorad + 3)
if c == BKG_COL then v = (c+128) % 255; c = matchcolor(v,v,v); end
db.drawRectangleLine(XP-sz,YP-sz,sz*2,sz*2,c)
end
 
end -- colz
 
 
 
-- Draw box
for n = 1, #lin, 1 do
l = lin[n]
p1 = boxp[l[1]]
p2 = boxp[l[2]]
x1,y1,z1 = p1[1],p1[2],p1[3]
x2,y2,z2 = p2[1],p2[2],p2[3]
draw3Dline(x1,y1,z1,x2,y2,z2,BOX_LINE_DIV,BOX_DIV_MULT,box_div)
 
end -- eof box
 
--updatescreen(); if (waitbreak(0.00)==1) then return; end
 
repeat
 
old_key = key;
old_mouse_x = mouse_x;
old_mouse_y = mouse_y;
old_mouse_b = mouse_b;
updatescreen()
moved, key, mouse_x, mouse_y, mouse_b = waitinput(0)
if mouse_b == 1 then ANIM = 0; end
 
if (key==27) then
return;
end
 
if (key==282) then ANIM = (ANIM+1) % 2; end -- F1: Stop/Start Animation
if (key==283) then initAndReset(); end -- F2: Reset all values
if (key==284) then COLSIZE_ADJ = COLSIZE_ADJ + 0.5; end -- F3
if (key==285) then COLSIZE_ADJ = COLSIZE_ADJ - 0.5; end -- F4
 
--messagebox(key)
 
if (key==286) then
--FG = (FG + 1) % 255;
palcol = (palcol + 1) % #pal
FG = pal[palcol+1][4]
setforecolor(FG);
setcolor(0,getcolor(0)) -- Force update of palette until setforecolor() is fixed
end -- F5
 
if (key==290) then -- F9
initColors("rgb")
initPointsAndLines("cube",BRIDIAG_SHOW)
end
if (key==291) then -- F10
initColors("hsl")
initPointsAndLines("cylinder", 0) -- Bridiag won't show even if turned on, it's only for cube
end
if (key==292) then -- F11
initColors("hsl_cubic")
initPointsAndLines("cube",BRIDIAG_SHOW)
end
 
if (key==269) then ZOOM = ZOOM + 0.1; end
if (key==270) then ZOOM = ZOOM - 0.1; end
 
if (key==32) then
ZSELECT = (ZSELECT + math.pi/2) % (2*math.pi);
--YANG = ((YANG - math.pi/2) % (math.pi*2));
--XANG = ((XANG + math.pi/2) % (math.pi*2));
 
YANG = ((YANG + math.pi/2) % (math.pi*2));
XANG = ((XANG + math.pi/2) % (math.pi*2));
YANG = ((YANG - math.pi/2) % (math.pi*2));
end -- Rotate Z 90 Degrees
 
SPEED = math.pi / 100
 
if (key==273) then WORLD_Y = WORLD_Y - 0.05; killinertia(); end
if (key==274) then WORLD_Y = WORLD_Y + 0.05; killinertia(); end
 
if (key==276) then WORLD_X = WORLD_X - 0.05; killinertia(); end
if (key==275) then WORLD_X = WORLD_X + 0.05; killinertia(); end
until ((mouse_b == 1 and (old_mouse_x~=mouse_x or old_mouse_y~=mouse_y)) or key~=0 or ANIM==1 or math.abs(XD)>0.01 or math.abs(YD)>0.01);
 
if ANIM == 0 then
if (mouse_b==1 and (old_mouse_x~=mouse_x or old_mouse_y~=mouse_y)) then -- Inertia
XD = (mouse_y - old_mouse_y)*0.005
YD = (mouse_x - old_mouse_x)*0.005
else
XD = XD*0.92
YD = YD*0.92
end
XANG = ((XANG - XD) % (math.pi*2));
YANG = ((YANG + YD) % (math.pi*2));
ZANG = ZSELECT
end
 
if ANIM == 1 then
XANG = (XANG + math.pi/300) % (math.pi*2)
YANG = (YANG + math.pi/500) % (math.pi*2)
ZANG = (ZANG + math.pi/1000) % (math.pi*2)
end
 
--XANG = ((CY-mouse_y) / 200 % (math.pi*2));
--YANG = ((mouse_x - CX) / 200 % (math.pi*2));
--ZANG = 0
 
statusmessage("x"..math.floor(XANG*57.3).."° y"..math.floor(YANG*57.3).."° z"..math.floor(ZANG*57.3).."° Zm: "..math.floor(-ZOOM*10).." ")
 
end
 
end -- OK
/data/common/media/grafx2/scripts/samples_2.4/demo/Ellipse.lua
0,0 → 1,68
--PICTURE scene: Ellipse update-demo (anim)
--Demonstrates 'interactive' features.
--by Richard Fhager
 
-- Copyright 2011 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
 
--
-- rot: Rotation in degrees
-- stp: Step is # of line segments (more is "better")
-- a & b are axis-radius
function ellipse2(x,y,a,b,stp,rot,col)
local n,m=math,rad,al,sa,ca,sb,cb,ox,oy,x1,y1,ast
m = math; rad = m.pi/180; ast = rad * 360/stp;
sb = m.sin(-rot * rad); cb = m.cos(-rot * rad)
for n = 0, stp, 1 do
ox = x1; oy = y1;
sa = m.sin(ast*n) * b; ca = m.cos(ast*n) * a
x1 = x + ca * cb - sa * sb
y1 = y + ca * sb + sa * cb
if (n > 0) then drawline(ox,oy,x1,y1,col); end
end
end
--
 
setpicturesize(300,300)
setcolor(0,96,96,96)
setcolor(1,255,255,128)
 
r1 = 100
r2 = 50
rt = 0
 
frames = 100
 
 
while (1 < 2) do
 
r1t = 10 + math.random() * 140
r2t = 10 + math.random() * 140
rtt = math.random() * 360
 
for n = 0, frames-1, 1 do
clearpicture(0)
 
f2 = n / frames
f1 = 1 - f2
 
r1a = r1*f1 + r1t*f2
r2a = r2*f1 + r2t*f2
rta = rt*f1 + rtt*f2
 
-- x, y, r1, r2, stp, rot, col
ellipse2(150, 150, r1a, r2a, 50, rta, 1)
 
statusmessage('press ESC to stop')
updatescreen();if (waitbreak(0)==1) then return end
 
end
 
r1,r2,rt = r1a,r2a,rta
 
end
/data/common/media/grafx2/scripts/samples_2.4/demo/FlipPicture.lua
0,0 → 1,17
-- flip picture - Copyright 2010 Paulo Silva
-- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. See <http://www.gnu.org/licenses/>
w,h=getpicturesize();
ok,flipx,flipy=inputbox("flip picture","flip x",1,0,1,-1,"flip y",0,0,1,-1);
if ok==true then
if flipx==1 then
for y=0,h-1,1 do
for x=0,w/2,1 do
c1=getpicturepixel(x,y);c2=getpicturepixel(w-x-1,y)
putpicturepixel(x,y,c2);putpicturepixel(w-x-1,y,c1)
end;end
else
for y=0,h/2,1 do
for x=0,w-1,1 do
c1=getpicturepixel(x,y);c2=getpicturepixel(x,h-y-1)
putpicturepixel(x,y,c2);putpicturepixel(x,h-y-1,c1)
end;end;end;end
/data/common/media/grafx2/scripts/samples_2.4/demo/SierpinskyCarpet.lua
0,0 → 1,59
--PICTURE: Pattern - Sierpinsky carpet v1.0
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
-- Email: dawnbringer@hem.utfors.se
-- MSN: annassar@hotmail.com
--
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
-- http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
--
 
frac = {{1,1,1},{1,0,1},{1,1,1}}
 
iter = 6
 
 
--
function pattern(x,y,p,n,i) -- Fractal Pattern V1.0 by Richard Fhager (mod allows for wrapping)
py = #p
px = #p[1]
while ((p[1+math.abs(math.floor(y*py))%py][1+math.abs(math.floor(x*px))%px]) == 1 and n<i) do
x=x*px-math.floor(x*px);
y=y*py-math.floor(y*py);
n = n+1
end
return 1 - n/i;
end
--
 
w, h = getpicturesize()
 
rp,gp,bp = getcolor(getforecolor())
 
 
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
 
ox = x / w;
oy = y / h;
 
f = pattern(ox,oy,frac,0,iter);
 
c = matchcolor(rp*f,gp*f,bp*f)
 
putpicturepixel(x, y, c);
end
updatescreen()
if (waitbreak(0)==1) then
return
end
 
end
 
/data/common/media/grafx2/scripts/samples_2.4/demo/SierpinskyTriangle.lua
0,0 → 1,57
--PICTURE: Pattern - Sierpinsky triangle v1.0
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
-- Email: dawnbringer@hem.utfors.se
-- MSN: annassar@hotmail.com
--
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
-- http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
--
 
frac = {{1,1},{1,0}}
 
iter = 15
 
--
function pattern(x,y,p,n,i) -- Fractal Pattern V1.0 by Richard Fhager (mod allows for wrapping)
py = #p
px = #p[1]
while ((p[1+math.abs(math.floor(y*py))%py][1+math.abs(math.floor(x*px))%px]) == 1 and n<i) do
x=x*px-math.floor(x*px);
y=y*py-math.floor(y*py);
n = n+1
end
return 1 - n/i;
end
--
 
w, h = getpicturesize()
 
rp,gp,bp = getcolor(getforecolor())
 
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
 
ox = x / w;
oy = y / h;
 
f = pattern(ox,oy,frac,0,iter);
 
c = matchcolor(rp*f,gp*f,bp*f)
 
putpicturepixel(x, y, c);
 
end
updatescreen()
if (waitbreak(0)==1) then
return
end
end
 
/data/common/media/grafx2/scripts/samples_2.4/demo/Spritesheet.lua
0,0 → 1,46
--ANIM: Sprite Animator v0.15
--Spare page holds data - Plays on current
--by Richard Fhager
 
run("../libs/memory.lua")
 
arg=memory.load({XS=16,YS=16,SPACE=1,FRAMES=8,XOFF=0,YOFF=0,FPS=10})
 
OK, XS, YS, SPACE, FRAMES, XOFF, YOFF, FPS = inputbox("Sprite-Sheet Animator",
"Sprite X-size", arg.XS, 1, 256,0,
"Sprite Y-size", arg.YS, 1, 256,0,
"Spacing", arg.SPACE, 0, 32,0,
"# of Frames", arg.FRAMES,2, 100,0,
"X-offset", arg.XOFF, 0, 800,0,
"Y-offset", arg.YOFF, 0, 800,0,
"Play Speed (FPS)",arg.FPS, 1, 60,0
);
 
 
if OK == true then
 
memory.save({XS=XS,YS=YS,SPACE=SPACE,FRAMES=FRAMES,XOFF=XOFF,YOFF=YOFF,FPS=FPS})
 
MAXPLAYS = 100
 
w,h = getpicturesize()
OX = w / 2 - XS/2
OY = h / 2 - YS/2
 
for play = 1, MAXPLAYS, 1 do
 
for f = 0, FRAMES-1, 1 do
for y = 0, YS-1, 1 do
for x = 0, XS-1, 1 do
sx = x + XOFF + f * (XS + SPACE)
sy = y + YOFF
putpicturepixel(OX+x, OY+y, getsparepicturepixel(sx, sy))
end
end
updatescreen(); if (waitbreak(1/FPS)==1) then return; end
end
 
end -- plays
 
end --OK
 
/data/common/media/grafx2/scripts/samples_2.4/demo/brush/Amigaball.lua
0,0 → 1,57
--BRUSH Scene: Amigaball 1.0
--
--Draws the famous 'Amiga ball' in the brush.
--
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
--http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
 
 
w, h = getbrushsize()
if (w<64 or h<64) then
setbrushsize(64,64)
w=64
h=64
end
 
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
 
-- Fractionalize image dimensions
ox = x / w;
oy = y / h;
 
-- Ball
Xr = ox-0.5; Yr = oy-0.5;
W = (1 - 2*math.sqrt(Xr*Xr + Yr*Yr));
 
-- 'FishEye' distortion / Fake 3D
F = (math.cos((ox-0.5)*math.pi)*math.cos((oy-0.5)*math.pi))*0.65;
ox = ox - (ox-0.5)*F;
oy = oy - (oy-0.5)*F;
 
-- Checkers
V = ((math.floor(0.25+ox*10)+math.floor(1+oy*10)) % 2) * 255 * W;
 
-- Specularities
SPEC1 = math.max(0,(1-5*math.sqrt((ox-0.45)*(ox-0.45)+(oy-0.45)*(oy-0.45)))*112);
SPEC2 = math.max(0,(1-15*math.sqrt((ox-0.49)*(ox-0.49)+(oy-0.48)*(oy-0.48)))*255);
 
r = W * 255 + SPEC1 + SPEC2
g = V + SPEC1 + SPEC2
b = V + SPEC1 + SPEC2
 
putbrushpixel(x, y, matchcolor(r,g,b));
 
end
end
/data/common/media/grafx2/scripts/samples_2.4/demo/brush/ColorSphere.lua
0,0 → 1,38
--BRUSH Scene: Sphere of pencolor v1.0
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
--http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
 
w, h = getbrushsize()
 
rp,gp,bp = getcolor(getforecolor())
 
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
 
-- Fractionalize image dimensions
ox = x / w;
oy = y / h;
 
-- Sphere
X = 0.5; Y = 0.5; Rd = 0.5
a = math.sqrt(math.max(0,Rd*Rd - ((X-ox)*(X-ox)+(Y-oy)*(Y-oy)))) * 1/Rd
r = rp * a
g = gp * a
b = bp * a
 
putbrushpixel(x, y, matchcolor(r,g,b));
 
end
end
/data/common/media/grafx2/scripts/samples_2.4/demo/brush/FindAA.lua
0,0 → 1,100
--BRUSH: Find AA-colors from pencolors
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
cellw = 8
cellh = 4
colors = 256
 
setbrushsize(cellw * 3, cellh * 3)
 
 
--
function makePalList(cols)
pal = {}
for n = 0, cols-1, 1 do
r,g,b = getcolor(n)
pal[n+1] = {r,g,b}
end
return pal
end
--
 
--
function getBestPalMatchHYBRID(rgb,pal,briweight)
local diff,diffC,diffB,best,bestcol,cols,n,c,r,g,b,p,obri,pbri
cols = #pal
bestcol = 0
best = 9e99
 
r = rgb[1]
g = rgb[2]
b = rgb[3]
 
obri = math.pow(r*9,2)+math.pow(g*16,2)+math.pow(b*8,2)
 
for n=0, cols-1, 1 do
p = pal[n+1]
pbri = math.pow(p[1]*9,2)+math.pow(p[2]*16,2)+math.pow(p[3]*8,2)
diffB = math.abs(obri - pbri)
 
 
diffC = (math.pow(r-p[1],2)+math.pow(g-p[2],2)+math.pow(b-p[3],2)) * 400
--diff = diffB + diffC
diff = briweight * (diffB - diffC) + diffC
if diff <= best then bestcol = n; best = diff; end
end
 
return bestcol
end
--
 
--
function drawRectangle(x1,y1,w,h,c)
for y = y1, y1+h, 1 do
for x = x1, x1+w, 1 do
putbrushpixel(x,y,c);
end
end
end
--
 
 
 
palList = makePalList(colors)
 
cf = getforecolor()
cb = getbackcolor()
rf,gf,bf = getcolor(cf)
rb,gb,bb = getcolor(cb)
 
ra = (rf + rb) / 2
ga = (gf + gb) / 2
ba = (bf + bb) / 2
 
rgb1 = {ra,ga,ba}
c1 = getBestPalMatchHYBRID(rgb1,palList,0.0)
c2 = getBestPalMatchHYBRID(rgb1,palList,0.75)
c3 = getBestPalMatchHYBRID(rgb1,palList,0.99)
 
q = {{cf,c1,cb},
{cf,c2,cb},
{cf,c3,cb}}
 
 
for y = 0, #q-1, 1 do
for x = 0, #q[1]-1, 1 do
drawRectangle(x*cellw,y*cellh,cellw,cellh,q[y+1][x+1])
 
end
end
 
 
/data/common/media/grafx2/scripts/samples_2.4/demo/brush/Mandelbrot.lua
0,0 → 1,64
--BRUSH Scene: Mandelbrot fractal v0.5
--
--Draws a Mandelbrot fractal in the current brush.
--
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
--http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
 
colors = 64
 
x0 = -1.7
x1 = 0.7
ym = 0
iter = 64
 
 
ok, x0, x1, ym, iter = inputbox("Fractal data",
"X0", x0, -2, 2,4,
"X1", x1, -2, 2,4,
"midY", ym, -2, 2,4,
"Iter", iter, 1, 2048,0
);
 
-- -0.831116819,-0.831116815,0.2292112435,192
 
 
function mandel(x,y,l,r,o,i) -- pos. as fraction of 1, left coord, right coord, y coord, iterations
 
local w,s,a,p,q,n,v,w
 
s=math.abs(r-l);
 
a = l + s*x;
p = a;
b = o - s*(y-0.5);
q = b;
n = 1;
v = 0;
w = 0;
 
while (v+w<4 and n<i) do n=n+1; v=p*p; w=q*q; q=2*p*q+b; p=v-w+a; end;
 
return n
end
 
 
w, h = getbrushsize()
 
for x = 0, w - 1, 1 do
for y = 0, h - 1, 1 do
q = mandel(x/w,y/h,x0,x1,ym,iter) % colors;
putbrushpixel(x, y, q);
end
end
/data/common/media/grafx2/scripts/samples_2.4/libs/dawnbringer_lib.lua
0,0 → 1,3720
--DawnBringer function library v1.14 (some drawing replaced)
--** THIS IS NOT A RUNNABLE SCRIPT! **
--by Richard Fhager
-- http://hem.fyristorg.com/dawnbringer/
-- Email: dawnbringer@hem.utfors.se
-- MSN: annassar@hotmail.com
--
-- Many functions in here was adopted from Evalion, a Javascript codecrafting/imageprocessing project
-- http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
--
--
-- You may access these functions in your own scripts by loading this library,
-- just add the follwing line as one of the first instructions:
--
-- run("dawnbringer_lib")
--
-- or
--
-- run("../libs/dawnbringer_lib.lua")
--
--
-- Note that the functions must be called with the full library object-name, "db.function_name..."
--
 
-- Global library object
db = {}
 
 
-- *************************************
-- *** Text & Conversions ***
-- *************************************
--
--
 
function db.rgb2HEX(r,g,b,prefix)
local c,n,s,t,z
c = {r,g,b}
z = {"0",""}
t = ""
for n = 1, 3, 1 do
s = string.upper(string.format("%x",c[n]))
t = t..z[#s]..s
--s = tonumber(c[n],16)
--t = t..s
end
return prefix..t
end
 
 
--
-- ... eof Text & Conversions ...
--
 
 
 
-- *************************************
-- *** Custom Math Functions ***
-- *************************************
--
--
function db.sign(v)
local s
s = 0
if v > 0 then s = 1; end
if v < 0 then s = -1; end
return s
end
--
 
function db.distance(ax,ay,bx,by) return math.sqrt((ax-bx)^2 + (ay-by)^2); end
 
--
function db.rotation (rot_ang,hub_x,hub_y,x,y) -- Rotate coordinates x & y relative hub
local new_ang,dist,m,xd,yd,v; m = math
xd=hub_x-x;
yd=hub_y-y;
if (not(xd==0 and yd==0)) then
v = -90; if xd < 0 then v = 90; end
new_ang = m.atan(yd/xd) - (v+rot_ang) * m.pi/180;
dist = m.sqrt(xd*xd+yd*yd);
x = hub_x - m.sin(new_ang)*dist;
y = hub_y + m.cos(new_ang)*dist;
end
return math.floor(x),math.floor(y) -- For drawing purposes
end
--
 
--
function db.recursiveSum(div,rlev) -- divisons per recursion,recursion levels
local s,i,m
s,m = 1,1
for i = 1, rlev, 1 do
m = m*div
s = s + m
end
return s
end
--
 
--
-- ... eof Custom Math Functions ...
--
 
-- *************************************
-- *** Fractional Scenery ***
-- *************************************
 
--
function db.setSceneryPalette()
db.colorCigarr(10,28,true) -- 250 colors
setcolor(250, 208,48,48)
setcolor(251, 48,208,48)
setcolor(252, 48,48,208)
setcolor(253, 224,224,64)
setcolor(254, 224,64,224)
setcolor(255, 64,224,224)
end
--
 
--
function db.star(xf,yf,sx,sy,rgb,haz,out,lum)
local n,c,dist; c={}
dist = haz + out * math.sqrt((xf-sx)^2+(yf-sy)^2);
for n = 1, 3, 1 do c[n] = (rgb[n] * lum) / dist; end
return c;
end
--
 
--
function db.zoom(xf,yf,zoom,panx,pany) -- Zoom and Pan in a fractional coord-system
xf = (xf-0.5)/zoom + 0.5 + panx;
yf = (yf-0.5)/zoom + 0.5 + pany;
return xf,yf
end
--
 
--
function db.rotationFrac(rot_ang,hub_x,hub_y,x,y) -- Rotate coordinates x & y relative hub
local new_ang,dist,m,xd,yd,v; m = math
xd=hub_x-x;
yd=hub_y-y;
if (not(xd==0 and yd==0)) then
v = -90; if xd < 0 then v = 90; end
new_ang = m.atan(yd/xd) - (v+rot_ang) * m.pi/180;
dist = m.sqrt(xd*xd+yd*yd);
x = hub_x - m.sin(new_ang)*dist;
y = hub_y + m.cos(new_ang)*dist;
end
return x,y
end
--
 
--
function db.twirl(x,y,arms,trot,tpow,tang)
local b,ang,vx,vy,vr,m,deg,tw
m=math; deg=math.pi/180; tw=.5;
if (not(x==.5 and y==.5)) then
ang = m.atan((.5-y)/(.5-x));
b = 0; if (x>.5) then b = m.pi; end
vx = .5-x; vy = .5-y; vr = m.pow(m.sqrt(vx*vx+vy*vy),tpow);
tw = .5+m.sin(-tang*deg+vr*trot+(ang + b)*arms)*.5;
end
return tw;
end
--
 
--- Alpha filters
--
function db.alpha1(x,y,amp) -- Coord, Amplify: 0..n
local p,a,xh,yh,m
xh=0.5-x; yh=0.5-y; m = math
p = m.pow(xh*xh+yh*yh,0.7);
a = m.cos(32*m.pi*p)*m.sin(8*m.pi*(xh+yh));
return 1 + (a * amp)
end
--
 
--
-- ... eof Fractional Scenery ...
--
 
-- *************************************
-- *** Custom Array Functions ***
-- *************************************
--
-- Ok, I don't know Lua that well (still unsure about some scopes & refs etc.)
-- And some features may not be active in Grafx2. So, some of the follwing functions
-- may exist in Lua/Grafx2...but since I'm not sure if and how they work - I'll prefer
-- to add a set of my own of known performance.
 
--
function db.newArrayInit(xs,val)
local x,ary; ary = {}
for x = 1, xs, 1 do
ary[x] = val
end
return ary
end
--
 
 
--
function db.newArrayInit2Dim(xs,ys,val)
local x,y,ary; ary = {}
for y = 1, ys, 1 do
ary[y] = {}
for x = 1, xs, 1 do
ary[y][x] = val
end
end
return ary
end
--
 
--
-- Merge two arrays into a NEW one: array_c = db.newArrayMerge(array_b,array_b)
--
function db.newArrayMerge(a,b)
local n,ary; ary = {}
for n = 1, #a, 1 do
ary[n] = a[n]
end
for n = 1, #b, 1 do
ary[n+#a] = b[n]
end
return ary
end
--
 
--
-- Generate a copy of an array with a new value added Last
--
function db.newArrayInsertLast(a,val)
local n,ary; ary = {}
for n = 1, #a, 1 do
ary[n] = a[n]
end
ary[#a+1] = val
return ary
end
--
 
--
-- Generate a copy of an array with a new value added First
--
function db.newArrayInsertFirst(a,val)
local n,ary; ary = {}
ary[1] = val
for n = 2, #a+1, 1 do
ary[n] = a[n-1]
end
return ary
end
--
 
--
function db.ary2txt(ary) -- One & two dimensions supported [a,b] -> "a,b". [[a,b],[c,d]] -> "a-b, c-d"
local t,n,m,v
t = ""
for n = 1, #ary, 1 do
if type(ary[n]) == "table" then
t = t..ary[n][1]
for m = 2, #ary[n], 1 do
t = t.."-"..ary[n][m]
end
else t = t..ary[n];
end
t = t..", "
end
return t
end
--
 
--
-- *** Array data manipulation ***
--
 
--
-- InsertionSort Array, this is chaos...I'm confused and stomped...don't understand how Lua works...
-- ...sorting seem be to ok but this code is ugly...
-- Sort LO-HI
--
-- Screwed up or confused thing here I think, perhaps lo-hi/hi-lo. This is working lo-hi but the code
-- looks like hi-lo...edit this some day
--
function db.sorti(d,idx)
local a,j,tmp,l,e
l = #d
 
for a=2, l, 1 do
tmp = d[a];
e = a
for j=a, 2, -1 do
e = j
if d[j-1][idx] > tmp[idx] then d[j] = d[j-1]; e = j-1; else break; end;
end;
d[e] = tmp; -- WHY THE F**K CAN'T YOU READ j HERE!?! STUPID ASSUCKING LANGUAGE
end;
--return d
end
--
 
--
function db.shuffle(list)
local i,n,t
for n = #list, 2, -1 do
i = 1+math.floor(math.random() * n)
t = list[n]; list[n] = list[i]; list[i] = t
end
end
--
 
--
-- ... eof Custom Array Functions ...
--
 
 
-- *************************************
-- *** Misc. Logical Operations ***
-- *************************************
 
--
-- palList [r,g,b,palindex] is expected only to contain unique colors
-- index = -1 --> index of list
--
function db.makeIndexList(list,index)
local n,ilist
ilist = {}
for n = 1, #list, 1 do
if (index > 0) then ilist[n] = list[n][index]; end
if (index == -1) then ilist[n] = n; end
end
return ilist
end
--
 
--
-- Return a list of all possible (non-same) pairs from the entries in a list
-- [a,b,c] --> [[a,b],[a,c],[b,c]]
-- (All entries are treated as unique. i.e it's only the INDEX that counts)
-- mode = 0: Only unique pairs (m = (n^2 - n)/2), [a,b] --> [[a,b]]
-- mode = 1: All pairs, i.e mirror versions as well. (m = n^2 - n), [a,b] --> [[a,b], [b,a]]
--
function db.pairsFromList(list,mode)
local a,b,l,n,pairs
pairs = {}
l = #list
n = 1
for a = 1, l, 1 do
for b = a+1, l, 1 do
pairs[n] = {list[a],list[b]}; n = n + 1
if mode == 1 then pairs[n] = {list[b],list[a]}; n = n + 1; end
end
end
return pairs
end
--
 
function db.valueInArray(ary,val)
local n,res
res = false
for n = 1, #ary, 1 do
if ary[n] == val then res = true; break; end
end
return res
end
 
-- RAMP specific
 
-- Remove initial pair (palList) colors from pallist
function db.initiateRamp(pair,pallist,pal_index)
local n,found,plist
plist = {}
 
found = 1
for n = 1, #pallist, 1 do
if db.valueInArray(pair,pallist[n]) == false then
plist[found] = pallist[n]; found = found + 1;
end
end
 
pair[pal_index] = plist -- ex: ["pal"]
 
return pair -- Is now a 2 color RAMP
end
--
 
-- Remove new col entry from ramp's pallist and add it to the ramp, returns an updated ramp
-- RampList = [1,2] ["pal"] = palList = [3,4,5], addindex = 3
-- --> [1,2,3] palList = [4,5]
function db.updateRamp(ramp,addindex,pal_index)
local n,found,pallist,plist,newramp
plist = {}
pallist = ramp[pal_index]
 
-- New palList without added color to IndexList
found = 1
for n = 1, #pallist, 1 do
if pallist[n] ~= addindex then
plist[found] = pallist[n]; found = found + 1;
end
end
 
newramp = db.newArrayInsertLast(ramplist,addindex)
newramp[pal_index] = plist
return rlist
end
 
--
-- Returns a list of all inital ramps from color pairs
--
-- Weeds out bad pairs, attaches remaining palette colors and the first rgb-vector
--
--
function db.initiateRampList(pairs,pallist,pal_index,vec_index,min,maxmult,rw,gw,bw)
local n,ramplist,newpairs,accept,dist,c1,c2,max,rD,gD,bD
ramplist = {}
max = min + (142 / math.sqrt(#pallist)) * maxmult -- min ex: 8-12
accept = 0
 
for n = 1, #pairs, 1 do
c1 = pallist[pairs[n][1]]
c2 = pallist[pairs[n][2]]
rD = c2[1] - c1[1]
gD = c2[2] - c1[2]
bD = c2[3] - c1[3]
dist = math.sqrt( (rw*rD)^2 + (gw*gD)^2 + (bw*bD)^2 )
 
if dist >= min and dist <= max then
accept = accept + 1; ramplist[accept] = db.initiateRamp(pairs[n],pallist,pal_index);
ramplist[accept][vec_index] = {rD, gD, bD, dist}; -- Add first color vector, ONLY KEEP DISTANCE?
end
end
 
return ramplist
end
 
 
function db.findRampExpansionColors(ramp)
local clist
clist = {}
-- Calculate vectors here?
return clist
end
 
 
function db.findRAMPS(min_len, max_len)
local i,n,c,pallist,ramp,ramplist,pairs,spairs,palindex,vecindex,found,donelist,newlist,dones
local colorlist
palindex = "pal"
vecindex = "vector"
pallist = db.fixPalette(db.makePalList(256), 0)
pairs = db.pairsFromList(db.makeIndexList(pallist,-1), 0)
ramplist = db.initiateRampList(pairs,pallist,palindex,vecindex, 8,0.75, 0.26,0.55,0.19)
 
-- MIN_LEN = 5
-- MAX_LEN = 10
 
-- Split Ramp-build into two parts:
-- 1. Build ramps >= MIN_LEN, NONE added to 'Done'
-- 2. Run til no more ramps can be expanded or reaches MAX_LEN, ALL ramps added to 'Done'
 
for i = 1, (min_len - 2), 1 do -- Assuming 2 for inital pairs (2 color ramps)
newlist = {}
found = 0
for n = 1, #ramplist, 1 do
ramp = ramplist[n]
colorlist = db.findRampExpansionColors(ramp) -- Colors that can split the current ramp into new expanded ramps
for c = 1, #colorlist, 1 do
found = found + 1; newlist[found] = db.updateRamp(ramp,colorlist[c],palindex); -- Ramp is expanded by 1 color
end
end
ramplist = newlist
end
 
 
donelist = {}; dones = 0
 
repeat
newlist = {}
found = 0
for n = 1, #ramplist, 1 do
ramp = ramplist[n]
if true == false then
found = found + 1; newlist[found] = db.updateRamp(ramp,color,palindex);
else
dones = dones + 1; donelist[dones] = ramp;
end
end
--ramplist = newlist
until found == 0
 
return #pairs.." - "..#ramplist
end
 
--
-- ... eof Misc. Logical Operations ...
--
 
 
-- ***************************************
-- *** General RGB-Color Modifications ***
-- ***************************************
 
 
--
function db.makeComplementaryColor(r,g,b,brikeeplev) -- Lev: 0 = Normal, 1 = Loose, 2 = Strict
 
local bri_o,bri_n,bdiff
 
function cap(v) return math.max(0,math.min(v,255)); end
 
bri_o = db.getBrightness(r,g,b)
r,g,b = db.shiftHUE(r,g,b,180)
 
if brikeeplev > 0 then
 
for n = 0, brikeeplev*3-1, 1 do -- Must iterate to reduce brightness error
bri_n = db.getBrightness(r,g,b)
bdiff = (bri_o - bri_n) / 2 * brikeeplev
r = cap(r + bdiff)
g = cap(g + bdiff)
b = cap(b + bdiff)
end
 
end
 
return r,g,b
 
end
--
 
 
-- *** Color balance ***
--
-- bri_flag: Preserve brightness
-- loose_flag: Loose preservation restrictions for brightness and balance
--
-- Jeez, was this a tricky sucker; color-balance is just adding and capping...
-- but trying color-balance with preserved perceptual brightness is a different monster...
-- ...so bad I could only solve it by iterative error correction.
--
function db.ColorBalance(r,g,b,rd,gd,bd,bri_flag,loose_flag) -- preserve brightness
local rw,gw,bw,ri,gi,bi,itot,rni,gni,bni,ro,go,bo,ovscale,lev,count,rt,gt,bt,rf,gf,bf,bri
 
-- Dawn 3.0, [0.26,0.55,0.19], 0-255 bri-colorscale adjust = 1.56905
rw,gw,bw = 0.26, 0.55, 0.19
 
function cap(v) return math.min(255,math.max(v,0)); end
bri = db.getBrightness(r,g,b)
 
 
-- Loose brightness & balance preservation, a good compromise.
if bri_flag == true and loose_flag == true then
 
lev = (rd + gd + bd) / 3
rd = rd - lev
gd = gd - lev
bd = bd - lev
 
brin = db.getBrightness(cap(r+rd),cap(g+gd),cap(b+bd))
itot = brin - bri
rd = rd - itot
gd = gd - itot
bd = bd - itot
 
end
 
 
if bri_flag == true and loose_flag == false then
 
itot = 255
count = 0
 
-- Normalize (Yup, it's right only to normalize once first..cont.norm. will have some counter-effect)
lev = (rd + gd + bd) / 3
rd = rd - lev
gd = gd - lev
bd = bd - lev
 
repeat
 
--messagebox("Norm:"..rd..", "..gd..", "..bd)
 
-- Calculate total brightness change
-- Note: Perceptual Brightness is exponential, and can't be delta-adjusted for anything other than greyscales.
-- Although the formula for the new brightness corrected normalization level can can be derived...
-- ...it doesn't do much good since the bigger problem is overflow outside the 0-255 boundary.
-- As for now, I see no other means to solve this issue than with iterative error-correction.
 
rt = r+rd
gt = g+gd
bt = b+bd
itot = 9e99
rni = rd
gni = gd
bni = bd
-- We can get brightness of negative values etc. So bri-correction is put on hold until values are scaled down
if (rt>=0 and gt>=0 and bt>=0) and (rt<256 and gt<256 and bt<256) then
brin = db.getBrightness(rt,gt,bt)
itot = brin - bri
--messagebox("Bri Diff: "..itot)
-- Brightness adjusted balance
rni = rd - itot
gni = gd - itot
bni = bd - itot
end
 
--messagebox("Bri Adj Bal:"..rni..", "..gni..", "..bni)
 
-- Apply balance to find overflow (as fraction of the channel change)
ro = math.max( math.max((r + rni)-255,0), math.abs(math.min((r + rni),0)) ) / math.max(math.abs(rni),1)
go = math.max( math.max((g + gni)-255,0), math.abs(math.min((g + gni),0)) ) / math.max(math.abs(gni),1)
bo = math.max( math.max((b + bni)-255,0), math.abs(math.min((b + bni),0)) ) / math.max(math.abs(bni),1)
 
ovscale = 1 - math.max(ro,go,bo)
 
-- Scaling balances might be logically incorrect (as they can be seen as constant differences)
-- But scaling DOWN is quite harmless and I don't see how it could be done otherwise...
-- ex: +10 red, +5 blue: Scale x2 = +20 red, +10 blue -> More red over blue than ordered, a contrast behaviour.
-- +10 red, +5 blue: Scale x0.5 = +5 red, +2.5 blue -> Less of everything, but a part of the order. Harmless?
--
rd = rni * ovscale
gd = gni * ovscale
bd = bni * ovscale
 
count = count + 1
 
--messagebox("Final bal:"..rd..", "..gd..", "..bd)
 
until math.abs(itot) < 1 or count > 5
 
end
 
rf = r + rd
gf = g + gd
bf = b + bd
 
--messagebox("Result color:"..rf..", "..gf..", "..bf)
 
return rf,gf,bf
end
--
 
 
 
--
-- bri_flag: Preserve brightness
-- cap_flag: Cap new color at 0-255, has a desaturating effect for large values.
--
function db.ColorBalanceXXX(r,g,b,rd,gd,bd,bri_flag,cap_flag) -- preserve brightness
local rf,gf,bf
 
if cap_flag == true then
rd = math.min(255,math.max(0, r+rd)) - r
gd = math.min(255,math.max(0, g+gd)) - g
bd = math.min(255,math.max(0, b+bd)) - b
end
 
local rw,gw,bw,ri,gi,bi,itot,rni,gni,bni,ro,go,bo,ovscale
 
 
-- Dawn 3.0, [0.26,0.55,0.19], 0-255 bri-colorscale adjust = 1.56905
rw,gw,bw = 0.26, 0.55, 0.19
 
if bri_flag == true then
 
-- Calculate total brightness change
--ri = rd * rw
--gi = gd * gw
--bi = bd * bw
--itot = math.sqrt(ri^2 + gi^2 + bi^2)
 
bri = db.getBrightness(r,g,b)
brin = db.getBrightness(r+rd,g+gd,b+bd)
itot = brin - bri
 
-- Normalized and Brightness adjusted balance
rni = rd - itot
gni = gd - itot
bni = bd - itot
 
-- Apply balance to find overflow (as fraction of the channel change)
ro = math.max( math.max((r + rni)-255,0), math.abs(math.min((r + rni),0)) ) / math.max(math.abs(rni),1)
go = math.max( math.max((g + gni)-255,0), math.abs(math.min((g + gni),0)) ) / math.max(math.abs(gni),1)
bo = math.max( math.max((b + bni)-255,0), math.abs(math.min((b + bni),0)) ) / math.max(math.abs(bni),1)
 
ovscale = 1 - math.max(ro,go,bo)
 
rd = rni * ovscale
gd = gni * ovscale
bd = bni * ovscale
 
end
 
rf = r + rd
gf = g + gd
bf = b + bd
 
return rf,gf,bf
end
--
 
--
function db.getContrast(ch) -- Channel, returns fraction -1..0..1, negative for ch < 127.5
--return math.abs((ch / 127.5) - 1)
return (ch / 127.5) - 1
end
--
 
--
function db.getAvgContrast(r,g,b)
return (math.abs(db.getContrast(r)) + math.abs(db.getContrast(g)) + math.abs(db.getContrast(b))) / 3
end
--
 
--
-- Mode = 0: Proportional - all colors reach max contrast at 100%
--
-- Mode = 1: Linear - percentage simply added
--
function db.changeContrastOLD(r,g,b,prc,mode)
 
local m,rd,gd,bd,rv,gv,bv,rc,gc,bc,base,sign
 
base = 1; sign = 1
if prc < 0 then base = 0; sign = -1; end -- decontrast
 
m = prc / 100 * sign
 
-- mode 0
rc = db.getContrast(r)
rd = (base - math.abs(rc)) * m * db.sign(rc)
rv = (rc+rd+1) * 127.5
 
gc = db.getContrast(g)
gd = (base - math.abs(gc)) * m * db.sign(gc)
gv = (gc+gd+1) * 127.5
 
bc = db.getContrast(b)
bd = (base - math.abs(bc)) * m * db.sign(bc)
bv = (bc+bd+1) * 127.5
 
return rv,gv,bv
 
end
--
 
function db.changeContrast(r,g,b,prc) -- Photoshop style
 
local m,rd,gd,bd,rv,gv,bv,rc,gc,bc
 
m = 1 + math.pow((255 / 100 * prc),3) / (255*255)
 
-- decontrast
if prc < 0 then
m = 1 - math.abs(prc)/100
end
rc = db.getContrast(r)
rd = rc * m
rv = (rd+1) * 127.5
 
gc = db.getContrast(g)
gd = gc * m
gv = (gd+1) * 127.5
 
bc = db.getContrast(b)
bd = bc * m
bv = (bd+1) * 127.5
 
return rv,gv,bv
 
end
 
 
 
--
function db.getBrightness(r,g,b) -- 0-255
local bri
--bri = (r+g+b)/3
--bri = r*0.3 + g*0.59 + b*0.11 -- Luma Y'601
--bri = math.sqrt((r*0.3)^2 + (g*0.59)^2 + (b*0.11)^2) -- Luma Y'601
--bri = r*0.245 + g*0.575 + b*0.18 -- Dawn 2.0
 
bri = math.sqrt((r*0.26)^2 + (g*0.55)^2 + (b*0.19)^2) * 1.56905 -- Dawn 3.0
return bri
end
--
 
 
--
-- Note on desaturation: These functions are all junk, the only way to desaturate
-- is to fade a color into it's corresponding greyscale.
--
 
--
function db.desaturate(percent,r,g,b) -- V1.0 by Richard Fhager
local a,p
p = percent / 100
a = (math.min(math.max(r,g,b),255) + math.max(math.min(r,g,b),0)) * 0.5 * p
r = r + (a-r*p) -- a+r*(1-p)
g = g + (a-g*p)
b = b + (a-b*p)
return r,g,b
end
--
 
--
function db.desaturateA(percent,c) -- array version
local r,g,b,a
r = c[1]
g = c[2]
b = c[3]
p = percent / 100
a = (math.min(math.max(r,g,b),255) + math.max(math.min(r,g,b),0)) * 0.5 * p
r = r + (a-r*p)
g = g + (a-g*p)
b = b + (a-b*p)
return {r,g,b}
end
--
 
--
function db.desatAVG(desat,c) -- Desaturation, simpe average
r = c[1]
g = c[2]
b = c[3]
p = desat / 100
a = (r+g+b)/3
r = r + p*(a-r)
g = g + p*(a-g)
b = b + p*(a-b)
return {r,g,b}
end
--
 
 
--
function db.getSaturation(r,g,b) -- HSL
local M,m,c,s,l
M = math.max(r,g,b)
m = math.min(r,g,b)
c = (M - m)/255
s = 0
if c ~= 0 then
--l = (0.3*r + 0.59*g + 0.11*b)/255 -- HSLuma: Y'601
l = (M+m)/510 -- This produces a quite "correct looking" divison of saturation
if l <= 0.5 then s = c / (2*l); end
if l > 0.5 then s = c / (2-2*l); end
end
return math.min(255,s * 255)
end
--
 
--
function db.getTrueSaturationX(r,g,b) -- Distance from grayscale axis. Not HSV/HSL
local sat,bri
bri = (r+g+b) / 3
sat = math.min(255, math.sqrt((r-bri)^2 + (g-bri)^2 + (b-bri)^2) * 1.224744875)
return sat
end
--
 
-- WIP. Trying to find a more natural model for estimating Saturation
-- Current: (HSL + True) / 2
function db.getAppSaturation(r,g,b)
return math.min(255, (db.getSaturation(r,g,b) + db.getTrueSaturationX(r,g,b)) / 2)
end
--
 
--
function db.saturate(percent,r,g,b)
local a,m,p,mc
a = (math.min(math.max(r,g,b),255) + math.max(math.min(r,g,b),0)) * 0.5
m = math.min(255-math.max(r,g,b), math.min(r,g,b))
p = percent * (m / 100)
mc = math.max((r-a),(g-a),(b-a)) -- Can this be derived elsewhere?
if mc ~= 0 then
r = r + (r-a) * p / mc
g = g + (g-a) * p / mc
b = b + (b-a) * p / mc
end
return r,g,b
end
--
 
--
-- Super Saturate: Better than Photoshop etc.
--
-- Higher than 100% power is ok
--
function db.saturateAdv(percent,r,g,b,brikeeplev,greydamp) -- brikeep = 0 - 2
local a,m,p,mc,bri_o,bri_n,bdiff,mx,mi,adj,q,n
function cap(v) return math.max(0,math.min(v,255)); end
mx = math.max(r,g,b)
mi = math.min(r,g,b)
bri_o = db.getBrightness(r,g,b)
a = (math.min(mx,255) + math.max(mi,0)) * 0.5
m = math.min(255-mx, mi)
p = percent * (m / 100)
mc = math.max((r-a),(g-a),(b-a)) -- Can this be derived elsewhere?
if mc ~= 0 and m ~= 0 then
adj = math.min(1,(mx - mi) / m) -- Reduce effect on low saturation
if greydamp == false then adj = 1; end
q = p / mc * adj
r = cap( r + (r-a) * q )
g = cap( g + (g-a) * q )
b = cap( b + (b-a) * q )
end
for n = 0, brikeeplev*2, 1 do -- Must iterate to reduce brightness error
bri_n = db.getBrightness(r,g,b)
bdiff = (bri_o - bri_n) / 2 * brikeeplev
r = cap(r + bdiff)
g = cap(g + bdiff)
b = cap(b + bdiff)
end
return r,g,b
end
--
 
 
--
-- Lightness: Darken / Brighten color (Argument and returnvalue is a rgb-list)
-- Rate of change is inversely proportional to the distance of the max/min.
-- i.e. all colors/channels will reach max/min at the same time (at 0 or 100 %)
-- (As opposed to 'Brightness' where all channels are changed by a constant value)
--
function db.lightness(percent,c)
local v,r,g,b,p
r = c[1]
g = c[2]
b = c[3]
p = math.abs(percent/100)
v = 255
if percent < 0 then v = 0; end
r = r + (v - r)*p
g = g + (v - g)*p
b = b + (v - b)*p
return {r,g,b}
end
--
 
--
function db.changeLightness(r,g,b,percent)
local v
v = db.lightness(percent,{r,g,b})
return v[1],v[2],v[3]
end
--
 
--
function db.getLightness(r,g,b) -- HSL bi-hexcone
return (math.max(r,g,b) + math.min(r,g,b)) / 2
end
--
 
--
function db.shiftHUE(r,g,b,deg) -- V1.3 R.Fhager 2007, (Heavily derived code, hehe...)
local c,h,mi,mx,d,s,p,i,f,q,t
c = {g,b,r}
mi = math.min(r,g,b)
mx = math.max(r,g,b); v = mx;
d = mx - mi;
s = 0; if mx ~= 0 then s = d/mx; end
p = 1; if g ~= mx then p = 2; if b ~= mx then p = 0; end; end
if s~=0 then
h=(deg/60+(6+p*2+(c[1+p]-c[1+(p+1)%3])/d))%6;
i=math.floor(h);
f=h-i;
p=v*(1-s);
q=v*(1-s*f);
t=v*(1-s*(1-f));
c={v,q,p,p,t,v}
r = c[1+i]
g = c[1+(i+4)%6]
b = c[1+(i+2)%6]
end
 
return r,g,b
end
--
 
--
function db.getHUE(r,g,b,greytol) -- 0-6 (6.5 = Greyscale), mult. with 60 for degrees
-- 1 Color diff is roughly detected by Tolerance = 0.0078125 (Tol. incr. with lightness etc.)
local c,h,mi,mx,d,s,p,i,f,q,t
c = {g,b,r}
mi = math.min(r,g,b)
mx = math.max(r,g,b); v = mx;
d = mx - mi;
s = 0; if mx ~= 0 then s = d/mx; end
p = 1; if g ~= mx then p = 2; if b ~= mx then p = 0; end; end
 
h = 6.5 -- for custom graphical purposes
if s>greytol then -- can't use >=
h=(6+p*2+(c[1+p]-c[1+(p+1)%3])/d)%6;
end
 
return h
end
--
 
--
-- ... eof RGB color modifications ...
--
 
 
 
-- ****************************************
-- *** Custom Color / Palette functions ***
-- ****************************************
 
 
--# of Unique colors in palette:
--#db.fixPalette(db.makePalList(256))
 
--# of Colors in Image:
--#db.makePalListFromHistogram(db.makeHistogram())
 
--# of Unique colors in Image:
--#db.fixPalette(db.makePalListFromHistogram(db.makeHistogram()))
 
--
function db.rgbcap(r,g,b,mx,mi)
local m = math
return m.max(mi,m.min(r,mx)), m.max(mi,m.min(g,mx)), m.max(mi,m.min(b,mx))
end
--
 
--
function db.rgbcapInt(r,g,b,mx,mi)
local m = math
return m.floor(m.max(mi,m.min(r,mx))), m.floor(m.max(mi,m.min(g,mx))), m.floor(m.max(mi,m.min(b,mx)))
end
--
 
 
--
function db.makePalList(cols)
local pal,n,r,g,b
pal = {}
for n = 0, cols-1, 1 do
r,g,b = getcolor(n)
pal[n+1] = {r,g,b,n}
end
return pal
end
--
 
--
function db.makeSparePalList(cols)
local pal,n,r,g,b
pal = {}
for n = 0, cols-1, 1 do
r,g,b = getsparecolor(n)
pal[n+1] = {r,g,b,n}
end
return pal
end
--
 
 
--
-- Use to remove the black colors (marks unused colors) from palette-list
-- if it's known that no black color exists in the image.
function db.stripBlackFromPalList(pallist)
local i,u,c,dummy; i = 257 -- Do 'nothing' If using a full 256 col palette with no blacks
for u = 1, #pallist, 1 do
c = pallist[u]
if (c[1]+c[2]+c[3]) == 0 then i = u; end
end
dummy = table.remove(pallist,i)
return pallist
end
--
 
--
function db.stripIndexFromPalList(pallist,colindex)
local i,u,c,dummy
for u = 1, #pallist, 1 do
c = pallist[u]
if c[4] == colindex then i = u; end
end
dummy = table.remove(pallist,i)
return pallist
end
--
 
--
function db.addHSBtoPalette(pallist)
local n,hue,sat,rgb
for n=1, #pallist, 1 do
rgb = pallist[n]
pallist[n][5] = db.getHUE(rgb[1],rgb[2],rgb[3],0)
pallist[n][6] = db.getSaturation(rgb[1],rgb[2],rgb[3])
pallist[n][7] = db.getBrightness(rgb[1],rgb[2],rgb[3])
end
return pallist -- {r,g,b,n,bri,hue,sat}
end
--
 
--
function db.makePalListRange(start,ends)
local pal,n,r,g,b,a
pal = {}
a = 1
for n = start, ends, 1 do
r,g,b = getcolor(n)
pal[a] = {r,g,b,n}; a = a + 1;
end
return pal
end
--
 
 
--
function db.makePalListShade(cols,sha) -- Convert colors to less bits, colorcube operations etc.
local pal,n,r,g,b,mf,div
mf = math.floor
div = 256 / sha
pal = {}
for n = 0, cols-1, 1 do
r,g,b = getcolor(n)
pal[n+1] = {mf(r/div),mf(g/div),mf(b/div),n}
end
return pal
end
--
--
function db.makePalListShadeSPARE(cols,sha) -- Convert colors to less bits, colorcube operations etc.
local pal,n,r,g,b,mf,div
mf = math.floor
div = 256 / sha
pal = {}
for n = 0, cols-1, 1 do
r,g,b = getsparecolor(n)
pal[n+1] = {mf(r/div),mf(g/div),mf(b/div),n}
end
return pal
end
--
 
 
 
--
function db.getColorDistance_weight(r1,g1,b1,r2,g2,b2,rw,gw,bw)
return math.sqrt( (rw*(r1-r2))^2 + (gw*(g1-g2))^2 + (bw*(b1-b2))^2 )
end
--
 
--
-- Since brightness is exponential, each channel may work as a "star" drowning the color
-- of a lesser channel. This algorithm is an approximation to adjust distances for this phenomenon.
-- Ex: Adding 32 red to black is visually obvious, but adding 64 red to full green is almost
-- impossible to detect by the naked eye.
--
-- However this isn't a complete solution so we may weigh in brightness as well...
--
-- If cv = 0 (0..1) then prox acts as ordinary perceptual colordistance
-- if bri = 1 (0..1) then distance is only that of brightness
function db.getColorDistanceProx(r1,g1,b1,r2,g2,b2,rw,gw,bw,normalizer, cv,briweight)
local rp1,gp1,bp1,rp2,gp2,bp2,v,m1,m2,prox,bdiff; v = 2*255*255
m1 = math.max(r1,g1,b1)
m2 = math.max(r2,g2,b2)
rp1 = 1 - math.sqrt((r1-m1)^2 / v) * cv
gp1 = 1 - math.sqrt((g1-m1)^2 / v) * cv
bp1 = 1 - math.sqrt((b1-m1)^2 / v) * cv
 
rp2 = 1 - math.sqrt((r2-m2)^2 / v) * cv
gp2 = 1 - math.sqrt((g2-m2)^2 / v) * cv
bp2 = 1 - math.sqrt((b2-m2)^2 / v) * cv
 
bdiff = math.abs(db.getBrightness(r1,g1,b1) - db.getBrightness(r2,g2,b2)) -- weights are hardcoded in function
prox = math.sqrt( (rw*(r1*rp1-r2*rp2))^2 + (gw*(g1*gp1-g2*gp2))^2 + (bw*(b1*bp1-b2*bp2))^2 ) * normalizer
 
return prox * (1-briweight) + bdiff * briweight
end
--
 
--
function db.getBestPalMatch(r,g,b,pal,index_flag) -- pal = [r,g,b,palindex], index_flag -> return palindex if pal is sorted or reduced
local diff,best,bestcol,cols,n,c,p
cols = #pal
bestcol = -1
best = 9e99
 
for n=1, cols, 1 do
p = pal[n]
diff = db.getColorDistance_weight(r,g,b,p[1],p[2],p[3],0.26,0.55,0.19) * 1.569
if diff < best then bestcol = n; best = diff; end
end
 
if index_flag == true then
bestcol = pal[bestcol][4] + 1
end
 
return bestcol-1 -- palList index start at 1, image-palette at 0
end
--
 
 
-- Normally this function will return the (image)palette index of best color
-- ...but if the palette has been sorted with 'fixPalette' it will return the index
-- of the custom palList, setting index_flag will convert this value to image-palette index
--
-- HYBRID means the colormatch is a combo of color and (perceptual)brightness
--
--
function db.getBestPalMatchHYBRID(rgb,pal,briweight,index_flag) -- Now correctly balanced
local diff,diffC,diffB,best,bestcol,cols,n,c,r,g,b,p,obri,pbri
cols = #pal
bestcol = -1
best = 9e99
 
--messagebox(briweight)
 
-- Note: Not secured against negative values (this algorithm is SLOW, we cannot afford it)
r = rgb[1]
g = rgb[2]
b = rgb[3]
 
obri = db.getBrightness(r,g,b) -- 0-255
 
for n=1, cols, 1 do
p = pal[n]
pbri = db.getBrightness(p[1],p[2],p[3])
diffB = math.abs(obri - pbri)
-- we need to normalize the distance by the weights
diffC = db.getColorDistance_weight(r,g,b,p[1],p[2],p[3],0.26,0.55,0.19) * 1.569
 
diff = briweight * (diffB - diffC) + diffC
if diff < best then bestcol = n; best = diff; end
end
 
if index_flag == true then
bestcol = pal[bestcol][4] + 1 -- Since we detract 1 on return, God Lua is stupid
end
 
return bestcol-1 -- palList index start at 1, image-palette at 0
end
--
 
 
 
--
-- Special version of Hybrid-remapping for mixPalette list
--
-- mixpal: {score,col#1,col#2,dist,rm,gm,bm, c1_r,c1_g,c1_b, c2_r,c2_g,c2_b}
--
-- returns: {col#1,col#2} (index of palette)
--
function db.getBestPalMatchHybridMIX(rgb,mixpal,briweight,mixreduction)
local diff,diffC,diffB,best,bestcol,cols,n,c,r,g,b,p,obri,pbri, distmult
cols = #mixpal
bestcol = -1
best = 9e99
 
-- We will simply add the the distance to the mix with the distance between the mixcolors and
-- employ a user tolerance to much the latter will matter.
--distmult = 255 / 9.56 / 100 * mixreduction -- 16 shades
distmult = 1.56902 / 100 * mixreduction -- 24-bit, Dawn3.0 colormodel
 
-- Note: Not secured against negative values (this algorithm is SLOW, we cannot afford it)
r = rgb[1]
g = rgb[2]
b = rgb[3]
 
obri = db.getBrightness(r,g,b) -- 0-255
 
for n=1, cols, 1 do
p = mixpal[n]
--pbri = db.getBrightness(p[5],p[6],p[7])
 
-- *** DawnBringer's exponetial color brightness dither resolution phenomena theorem ***
-- Bri = color value ^ 2
-- Two adjacent pixels displayed with "normal high resolution" will NOT have the perceptual
-- brightness of the resulting mixcolor. The brightness lies closer to that of the brightest pixel.
-- Bri[(C1+C2)/2] = SQRT( (C1bri^2 + C2bri^2) / 2 )
-- (Brightness according to Dawn-model: bri = SQRT( (r*.26)^2 + (g*.55)^2 + (b*.19)^2 ) )
 
pbri = math.sqrt((db.getBrightness(p[8],p[9],p[10])^2 + db.getBrightness(p[11],p[12],p[13])^2) / 2)
 
diffB = math.abs(obri - pbri)
-- we need to normalize the distance by the weights
diffC = db.getColorDistance_weight(r,g,b,p[5],p[6],p[7],0.26,0.55,0.19) * 1.569 + p[4]*distmult
 
diff = briweight * (diffB - diffC) + diffC
if diff <= best then bestcol = n; best = diff; end
end
 
return {mixpal[bestcol][2], mixpal[bestcol][3]}
--return {mixpal[bestcol][2], 0}
 
 
 
end
--
 
 
 
--
function db.matchcolorHSB(h,s,b,pallist,index_flag)
--
-- why don't we just convert HSB-diagram to RGB and do normal colormatching?
-- Not the same...
--
local n,c,best,bestcol,pb,ph,ps,diff,huediff,huecorr,hue_adj,sat_adj,bri_adj
bestcol = -1
best = 9e99
-- higher adjust means more impact (higher hue gives more interpolation )
hue_adj = 4
sat_adj = 0.075
bri_adj = 2
 
huecorr = 255 / 6 -- Our Hue goes from 0.0 - 5.999
 
for n=1, #pallist, 1 do
c = pallist[n]
ph = c[5]
ps = c[6]
pb = c[7]
 
huediff = math.abs(h-ph*huecorr)
if huediff > 127 then huediff = huediff - (huediff % 127) * 2; end
 
--if ph == 6.5 then huediff = 0; end
 
-- With less saturation, exact hue becomes less important and brightness more usefull
-- This allows for greyscales and low saturation colors to work smoothly.
huediff = huediff * (ps /255)
 
diff = hue_adj*huediff^2 + (s-ps)^2 * sat_adj + (b-pb)^2 * bri_adj
if diff <= best then bestcol = n; best = diff; end
end
 
if index_flag == true then
bestcol = pallist[bestcol][4] + 1 -- Since we detract 1 on return, God Lua is stupid
end
 
return bestcol-1
 
end
--
 
--
-- Used by PaletteAnalysis.lua, FindRamps(), MixColors() etc.
-- Assigns is used by ApplySpare script
--
function db.fixPalette(pal,sortflag) -- Arrange palette & only keep unique colors
 
local n,l,rgb,i,unique,bri,hue,sat,ulist,indexpal,newpal,dtot
ulist = {}
indexpal = {}
newpal = {}
local doubles,assign
doubles = {}; assign = {}
 
l = #pal
 
unique = 1 -- ok, see how stupid lua is
dtot = 0
for n=1, l, 1 do
rgb = pal[n]; -- actually rgbn
i = 1 + rgb[1] * 65536 + rgb[2] * 256 + rgb[3];
bri = db.getBrightness(rgb[1],rgb[2],rgb[3])
if indexpal[i] == nil then
indexpal[i] = rgb; ulist[unique] = {i,bri}; unique = unique+1;
assign[rgb[4]+1] = rgb[4] -- really n, but can we be sure?
else
doubles[rgb[4]] = true; -- Mark as double (This is wrong; starts at 0...but col 0 cannot be a double so...)
dtot = dtot + 1
assign[rgb[4]+1] = indexpal[i][4] -- Reassign removed color
end
end
 
-- sort ulist
if sortflag == 1 then db.sorti(ulist,2); end -- sort by brightness
 
l = #ulist
for n=1, l, 1 do
newpal[n] = indexpal[ulist[n][1]]
end
 
newpal["assigns"] = assign -- Complete list of image color assigns (removed cols will point to 1st occurence)
newpal["doubles"] = doubles
newpal.double_total = dtot
 
--messagebox("unique colors", unique-1)
 
return newpal
 
end
--
 
--
function db.drawColorspace12bit(x,y,cols,size)
local r,g,b,c,rows,row,col,s16,rx,ry,xx,yy
s16 = size*16
rows = math.floor(16/cols)
 
for g = 0, 15, 1 do
col = g % cols
row = math.floor(g / cols)
for r = 0, 15, 1 do
for b = 0, 15, 1 do
c = matchcolor(r*17,g*17,b*17)
xx = x+col*s16+r*size
yy = y+row*s16+b*size
for ry = 0, size-1, 1 do
for rx = 0, size-1, 1 do
putpicturepixel(xx+rx,yy+ry,c)
end;end
end
end
end
end
--
 
--
function db.drawHSBdiagram(pallist,posx,posy,width,height,size,sat)
--db.addHSBtoPalette(palList)
local x,y,c
for y = 0, height-1, 1 do
for x = 0, width-1, 1 do
hue = 255/width * x
bri = 255/height * y
c = db.matchcolorHSB(hue,sat,bri,pallist,true)
db.drawRectangle(posx + x*size, posy + y*size,size,size, c)
end
end
end
--
 
--
function db.polarHSBdiagram(ox,oy,radius,pol,brilev,huelev,saturation,dark2bright_flag)
 
local pal,bstep,bstep2,hstep,hstep2,bri,hue,sx,sy,cx,cy,x,y,p1,p2,c
 
pal = db.addHSBtoPalette(db.fixPalette(db.makePalList(256)))
 
bstep = radius / (brilev + pol)
bstep2 = bstep / 2
hstep = -360 / huelev
hstep2 = hstep / 2
 
c = 255; if dark2bright_flag then c = 0; end
drawdisk(ox,oy,math.ceil(pol*bstep),matchcolor(c,c,c))
 
for y=pol, brilev+pol-1,1 do
bri = (brilev - y + pol) * (256 / brilev)
 
if dark2bright_flag then
bri = (brilev - (brilev - y + pol)) * (256 / brilev)
end
 
for x=0, huelev-1,1 do
 
hue = x * (360 / huelev) * 255/360
 
c = db.matchcolorHSB(hue,saturation,bri,pal,true)
 
sx = ox
sy = oy - y*bstep
 
cx,cy = db.rotationFrac(x*hstep,ox,oy,sx,sy)
 
x1,y1 = db.rotation(x*hstep-hstep2,ox,oy,ox, sy-bstep2)
x2,y2 = db.rotation(x*hstep+hstep2,ox,oy,ox, sy-bstep2)
x3,y3 = db.rotation(x*hstep-hstep2,ox,oy,ox, sy+bstep2)
x4,y4 = db.rotation(x*hstep+hstep2,ox,oy,ox, sy+bstep2)
 
p1 = {{x1,y1},{x2,y2},{x3,y3}}
p2 = {{x3,y3},{x4,y4},{x2,y2}}
 
db.fillTriangle(p1,c,0,true,false) -- triangle, fillcol, linecol, fill, wire
db.fillTriangle(p2,c,0,true,false)
 
end
updatescreen(); if (waitbreak(0)==1) then return; end
end
 
end -- polarHSB
--
 
 
--
-- Histograms, remapping etc.
--
 
--
function db.makeHistogram()
local n,y,x,c,w,h,list; list = {}
w, h = getpicturesize()
for n = 1, 256, 1 do list[n] = 0; end
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
c = getpicturepixel(x,y)
list[c+1] = list[c+1] + 1
end
end
return list
end
--
 
--
function db.makeHistogramIndexed() -- With color index so it can be sorted etc.
local n,y,x,c,w,h,r,g,b,list; list = {}
w, h = getpicturesize()
for n = 1, 256, 1 do
r,g,b = getcolor(n-1)
list[n] = {0,n-1,r,g,b};
end
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
c = getpicturepixel(x,y)
list[c+1][1] = list[c+1][1] + 1
end
end
return list
end
--
 
--
function db.makeSpareHistogram()
local n,y,x,c,w,h,list; list = {}
w, h = getsparepicturesize()
--w,h = 512,360
for n = 1, 256, 1 do list[n] = 0; end
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
c = getsparepicturepixel(x,y)
list[c+1] = list[c+1] + 1
end
end
return list
end
--
 
 
--
-- Makes a palette-list from only the colors (histogram) that occurs in the image
-- Assumes image/palette has not changed since histogram was created
function db.makePalListFromHistogram(hist)
local n,r,g,b,list,count
list = {}
count = 1
for n = 1, #hist, 1 do
if hist[n] > 0 then
r,g,b = getcolor(n-1)
list[count] = {r,g,b,n-1}
count = count + 1
end
end
return list
end
--
 
function db.makePalListFromSpareHistogram(hist)
local n,r,g,b,list,count
list = {}
count = 1
for n = 1, #hist, 1 do
if hist[n] > 0 then
r,g,b = getsparecolor(n-1)
list[count] = {r,g,b,n-1}
count = count + 1
end
end
return list
end
--
 
 
--
function db.remap(org) -- Working with a remap-list there's no need of reading backuppixel
--messagebox("Remapping")
local x,y,c,i,w,h,s,f,col
f = getpicturepixel
s = false
w, h = getpicturesize()
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
c = f(x,y)
i = org[c+1]
if i == null then i = matchcolor(getbackupcolor(getbackuppixel(x,y))); s = true; col = c; end -- Find color for a removed double
putpicturepixel(x,y,i)
end
end
if s then messagebox("Remapping: Not all image colors were found in remap-list (re-assign), probably due to duplicate removal. Matchcolor was used, ex: col# "..col);
end
end
--
 
--
-- Same as db.remap but no comments
--
function db.remapImage(colassignlist) -- assignment list is optional
local x,y,c,w,i,h,assign
assign = false
if colassignlist ~= null then assign = true; end
w,h = getpicturesize()
for y = 0, h-1, 1 do
for x = 0, w-1, 1 do
c = getbackuppixel(x,y)
i = null; if assign then i = colassignlist[c+1]; end
if not assign or i == null then
i = matchcolor(getbackupcolor(c))
end
putpicturepixel(x,y,i)
end
end
end
--
 
--
-- Palette DeCluster: Color-reduction by fusing similar colors into new ones, using a desired tolerance.
-- This is a method similar to Median-Cut, but more surgical.
--
-- pallist: Palette list {r,g,b,palette_index}
-- hist: Histogram {color 0 pixels, color 1 pixels...etc} always a full 256 color list
-- crad: Cluster radius treshold in % of distance between black & white
-- A value of 0 will only remove identical colors
-- A value of 3-4 will usally fuse redundant colors without causing notice
-- prot_pow: (0..10) Protect common colors in histogram. Distances are increased by ocurrence.
-- Also gives protection to fused colors even if not using histogram (combined nominal weights)
-- pixels: Pixels in image (so protection can be calculated)
-- rw,gw,bw: Color weights (rw+gw+bw = 1, 0.33,0.33,0.33 is nominal)
--
-- Returns:
-- a new (c)palette list {r,g,b,{original palette_indices},fused flag, histogram_weight}
-- a remap list (org) [image color + 1] = remap color (in the new palette)
function db.deCluster(pallist, hist, crad, prot_pow, pixels, rw,gw,bw)
 
--messagebox(pixels)
 
local u,c,a,i,o,j,n,c1,c2,r,g,b,r1,g1,b1,r2,g2,b2,wt,rt,gt,bt,tot,pd
local worst,wtot,maxdist,maxDist,distfrac,clusterExists,clustVal,count,crad1
local cList,cPalList,clusterList,fuseCol,orgcols,newPalList,org
 
maxdist = math.sqrt(rw*rw*65025 + gw*gw*65025 + bw*bw*65025)
distfrac = 100 / maxdist
 
-- Let's just make a slightly more suitable format of the pallist (List for original color(s))
cPalList = {}
for u = 1, #pallist, 1 do
c = pallist[u]
cPalList[u] = {c[1],c[2],c[3],{c[4]},false,hist[c[4]+1]} -- r,g,b,{original colors},fuse_marker,histogram_weight
end
 
--table.insert(cPalList,{255,255,0,{257},false,1})
 
clusterExists = true
while clusterExists do
clusterExists = false
clusterList = {}
 
crad1 = crad + 1 -- avoid divison by zero
worst = 9999
for a = 1, #cPalList, 1 do
c1 = cPalList[a]
r1,g1,b1 = c1[1],c1[2],c1[3]
wtot = c1[6]
cList = {a}
maxDist = 0
for b = 1, #cPalList, 1 do
if (b ~= a) then
c2 = cPalList[b]
r2,g2,b2 = c2[1],c2[2],c2[3]
wt = c2[6]
pd = math.pow((1 + wt / pixels), prot_pow) -- Protection, increase distance
dist = db.getColorDistance_weight(r1,g1,b1,r2,g2,b2,rw,gw,bw) * distfrac * pd
if dist <= crad then
wtot = wtot + wt
table.insert(cList,b)
maxDist = math.max(dist,maxDist)
end
end
end -- b
if #cList > 1 then
clustVal = maxDist / (crad1 * #cList) * (wtot / #cList)
if clustVal < worst then
worst = clustVal
clusterList = cList
end
end
end -- a
--t = db.ary2txt(clusterList)
--messagebox("Worst cluster is "..t)
-- Fuse
if #clusterList > 1 then
clusterExists = true -- Run another iteration and look for more clusters
fuseCol = {0,0,0,{}}
rt,gt,bt,tot = 0,0,0,0
for n = 1, #clusterList, 1 do
i = clusterList[n]
c = cPalList[i]
--o = c[4][1] -- Original color (always #1 in list since fused colors can't re-fuse)
o = c[4] -- Original color list
--if c[5] == true then messagebox("Re-Fusing..."); end
r,g,b = c[1],c[2],c[3]
--wt = hist[o+1] -- Org. colors are 0-255
wt = c[6]
rt = rt + r * wt
gt = gt + g * wt
bt = bt + b * wt
tot = tot + wt
cPalList[i] = -1 -- Erase color
--table.insert(fuseCol[4],o)
orgcols = fuseCol[4]
for j = 1, #o, 1 do
table.insert(orgcols,o[j])
end
fuseCol[4] = orgcols
end
 
rt = rt / tot
gt = gt / tot
bt = bt / tot
fuseCol[1] = rt
fuseCol[2] = gt
fuseCol[3] = bt
fuseCol[5] = true -- fusecol marker
fuseCol[6] = tot
table.insert(cPalList,fuseCol)
--messagebox(#clusterList.." Colors was fused, resulting in "..rt..", "..gt..", "..bt)
newPalList = {}
for n = 1, #cPalList, 1 do
if cPalList[n] ~= -1 then
table.insert(newPalList,cPalList[n])
--newPalList = db.newArrayInsertLast(newPalList,cPalList[n])
end
end
cPalList = newPalList
--messagebox("Pal length: "..#cPalList)
statusmessage("DC - Image colors: "..#cPalList.." "); waitbreak(0)
end -- fuse
 
end -- while
 
-- Create remap-list
org = {}
count = 0
for u = 1, #cPalList, 1 do
c = cPalList[u]
for n = 1, #c[4], 1 do
i = c[4][n]
org[i+1] = count -- quick way to remap without matchcolor
end
count = count + 1
end
 
return org,cPalList
 
end; -- decluster
 
 
 
-- ------------- MEDIAN CUT V1.0 ------------
--
-- 256 color Palette Lua-version (converted from Evalion JS-script)
--
-- by Richard 'DawnBringer' Fhager
--
--
-- pal: [[r,g,b,i]] Pallist
-- cnum: Target number of colors in reduced palette
-- (step:) 1.. Pixel picks for processing, 1 = all pixels in image, best and slowest. 2 = 25% of pixels
-- qual: Flag Qualitative color selection (Normal mode)
-- quant: Flag Quantative color/pixel selection (Histogram) 100% mean that it count as much as quality
-- (One of or both qual/quant must be selected)
-- rgbw: [3] RGB-weights []. Weigh the color channels. ex: [1,1.333,0.75]
-- bits: 1-8 Bits used for each color channel in palette
-- quantpow: 0..1
--
-- return: A palette! A list of [r,g,b] values
--
-- NOTE: Quantity will act as a counterforce to altered colorspace (weights)...
-- Ex: if Green is considered bigger, it will be split into more blocks
-- but each blocks will have less colors and thus less quantity.
--
-- Perceptual colorspace (rgb-weights) will generally produce the best quality of palettes, but if
-- It's desirable to preserve stronger colors, esp. in small palettes,
-- it can be good to just use nominal space: 1,1,1
--
-- Histogram may be useful to assign more colors to an object that already covers most of the image,
-- however; if the object of interest is small in relation to a large (unimportant) background, it's
-- usually best not to have any histogram at all. Histogram will dampen strong infrequent colors.
 
 
function db.medianCut(pal,cnum,qual,quant,rgbw,bits,quantpow)
local n,x,y,xs,ys,rgb,blocklist,blocks
local len,res,chan,diff,maxdiff,maxblock,split
local qualnorm, quantnorm
 
-- Normalize 256 for quality/quantity relationship
qualnorm = 1 / math.sqrt(rgbw[1]^2 + rgbw[2]^2 + rgbw[3]^2)
quantnorm = 256 / #pal
 
blocklist = {}
blocklist[1] = {}; blocks = 1
 
for n=1, #pal, 1 do
blocklist[1][n] = pal[n];
end
 
analyzeBlock(blocklist[1],qual,quant,rgbw,qualnorm,quantnorm,quantpow)
 
failsafe = 0
while (blocks < cnum and failsafe < 256) do
failsafe = failsafe + 1
maxdiff = -1
maxblock = -1
for n=1, blocks, 1 do
diff = blocklist[n].diff
if (diff > maxdiff) then maxdiff = diff; maxblock = n; end -- maxchan is stored as .chan in block
end
split = splitBlock(blocklist,maxblock,qual,quant,rgbw,qualnorm,quantnorm,quantpow)
--if (split == false){ alert("Only found " + blocks + " (24-bit) colors!"); break; }
blocks = #blocklist
--status.value = "MC: " +blocks
end -- while
 
return blocks2Palette(blocklist,bits)
 
end
--
 
--
function blocks2Palette(blocklist,bits)
local n,r,g,b,c,pal,block,rgb,blen,M,dB,cB,rf,gf,bf
M = math
pal = {}
 
--bits = 1
dB = M.pow(2,8-bits)
cB = M.ceil(255 / (M.pow(2,bits) - 1))
 
for n=1, #blocklist, 1 do
block = blocklist[n]
r,g,b = 0,0,0
blen = #block
for c=1, blen, 1 do
rgb = block[c]
r = r + rgb[1]
g = g + rgb[2]
b = b + rgb[3]
end
 
rf = M.floor(M.min(255,M.max(0,M.floor(r/blen))) / dB) * cB
gf = M.floor(M.min(255,M.max(0,M.floor(g/blen))) / dB) * cB
bf = M.floor(M.min(255,M.max(0,M.floor(b/blen))) / dB) * cB
 
pal[n] = {rf, gf, bf, 0} -- col is avg. of all colors in block (index is set (to 0) for compatibility)
end -- blocklist
 
return pal
end
--
 
--
function analyzeBlock(block,qual,quant,rgbw,qualnorm,quantnorm,quantpow)
local r,g,b,n,rmin,gmin,bmin,rmax,gmax,bmax,rdif,gdif,bdif,chan,d,median,diff
local len,Mm,Mx,rgb,kv,qu
Mx,Mm = math.max, math.min
len = #block
 
rmin,gmin,bmin = 255,255,255
rmax,gmax,bmax = 0,0,0
 
for n=1, len, 1 do
rgb = block[n]
r = rgb[1] * rgbw[1]
g = rgb[2] * rgbw[2]
b = rgb[3] * rgbw[3]
--if (!isNaN(r) and !isNaN(g) and !isNaN(b)) then -- Ignore any erroneous data
rmin = Mm(rmin,r)
gmin = Mm(gmin,g)
bmin = Mm(bmin,b)
rmax = Mx(rmax,r)
gmax = Mx(gmax,g)
bmax = Mx(bmax,b)
--end
end
rdif = (rmax - rmin) -- * rgbw[1]
gdif = (gmax - gmin) -- * rgbw[2]
bdif = (bmax - bmin) -- * rgbw[3]
 
d = {{rmin,rdif,rmax},{gmin,gdif,gmax},{bmin,bdif,bmax}}
 
chan = 1 -- Widest channel
if (gdif > rdif) then chan = 2; end
if (bdif > rdif and bdif > gdif) then chan = 3; end
-- Ok, this is the average of the max/min value rather than an actual median
-- I guess this will fill the colorspace more uniformly and perhaps select extremes to a greater extent?
-- Which is better?
--median = d[chan][1] + d[chan][2] / 2 -- OLD same as median with nominal weights
median = (d[chan][1] + d[chan][3]) / 2
 
-- quantity and quality are normalized to 256 (256 is the total of colors in the set for quantity)
-- Note that, regardless of forumla, quality (distance) must always be greater in any block than quantity (colors/pixels)
-- Coz a block may contain many of only 1 unique color, thus rendering it impossible to split if selected.
kv = 1
qu = 1
if (quant) then kv = 1 + len*quantnorm*quantpow; end
if (qual) then qu = d[chan][2] * qualnorm; end
diff = qu + qu*kv^2.5
 
block.chan = chan
block.diff = diff
block.median = median
 
return {chan,diff,median,len}
 
end
--
 
function splitBlock(blocklist,maxblock,qual,quant,rgbw,qualnorm,quantnorm,quantpow)
local n,cmax,median,blockA,blockB,len,cB,block,rgb,res
blockA,blockB = {},{}
block = blocklist[maxblock]
 
res = true
 
chan = block.chan
median = block.median
 
cB = blocklist[maxblock] -- maxblock starts at 1 when called so it should not hava a +1
len = #cB
 
for n=1, len, 1 do
rgb = cB[n]
--if (rgb[chan] >= median) then blockA.push(rgb); end
--if (rgb[chan] < median) then blockB.push(rgb); end
if (rgb[chan]*rgbw[chan] >= median) then table.insert(blockA,rgb); end
if (rgb[chan]*rgbw[chan] < median) then table.insert(blockB,rgb); end
end
 
blocklist[maxblock] = blockA -- Can't be empty right?
analyzeBlock(blocklist[maxblock],qual,quant,rgbw,qualnorm,quantnorm,quantpow)
 
if (#blockB > 0) then
table.insert(blocklist,blockB)
analyzeBlock(blocklist[#blocklist],qual,quant,rgbw,qualnorm,quantnorm,quantpow) -- no -1 on blocklist
else
res = false
end
 
return res -- false = no split
end
 
------------ eof MEDIAN CUT --------------------------
 
 
-- ------------- MEDIAN REDUX V1.0 ------------
--
-- Divide space by greatest distance of any two colors (rather than MC-method of any given channel)
-- Basically it allows colorspace to be sliced at any angles rather than the "boxing" of MC.
--
--
-- by Richard 'DawnBringer' Fhager
--
--
-- pal: [[r,g,b,i,h]] Pallist (h = histogram/pixelcount)
-- cnum: Target number of colors in reduced palette
-- (step:) 1.. Pixel picks for processing, 1 = all pixels in image, best and slowest. 2 = 25% of pixels
-- qual: Flag Qualitative color selection (Normal mode)
-- quant: Flag Quantative color/pixel selection (Histogram) 100% mean that it count as much as quality
-- (One of or both qual/quant must be selected)
-- rgbw: [3] RGB-weights []. Weigh the color channels. ex: [0.26, 0.55, 0.19]
-- bits: 1-8 Bits used for each color channel in palette
-- quantpow: 0..1 Quantity vs Quality (put weight into histogram/pixelcount)
-- briweight: 0..1 Brightness distance weight in colordistance
-- proxweight: 0..1 Primary Proximity distance weight in colordistance (ColorTheory-WIP: compensate for brightness of individual channels, the "extra power" of primary colors)
--
-- return: A palette! A list of [r,g,b] values
--
-- NOTE: Quantity will act as a counterforce to altered colorspace (weights)...
-- Ex: if Green is considered bigger, it will be split into more blocks
-- but each blocks will have less colors and thus less quantity.
--
-- Perceptual colorspace (rgb-weights) will generally produce the best quality of palettes, but if
-- It's desirable to preserve stronger colors, esp. in small palettes,
-- it can be good to just use nominal space: 0.33, 0.33, 0.33
--
-- Histogram may be useful to assign more colors to an object that already covers most of the image,
-- however; if the object of interest is small in relation to a large (unimportant) background, it's
-- usually best not to have any histogram at all. Histogram will dampen strong infrequent colors.
 
 
function db.medianRedux(pal,cnum,qual,quant,rgbw,bits,quantpow, briweight, proxweight) -- pal[r,g,b,i,pixelcount]
local n,x,y,xs,ys,rgb,blocklist,blocks
local len,res,chan,diff,maxdiff,maxblock,split
local qualnorm, quantnorm,count
 
blocklist = {}
blocklist[1] = {}; blocks = 1
 
count = 0
for n=1, #pal, 1 do
blocklist[1][n] = pal[n];
count = count + pal[n][5]
end
 
-- Normalize 256 for quality/quantity relationship
qualnorm = 1 / math.sqrt(rgbw[1]^2 + rgbw[2]^2 + rgbw[3]^2)
quantnorm = 256 / count
 
 
-- Dist table
statusmessage("MR: Making Distance Table..."); updatescreen(); if (waitbreak(0)==1) then return; end
local dy,c,r1,g1,b1,i1,i2
dt = {}
for n=1, #pal, 1 do
c = pal[n]
r1,g1,b1,i1 = c[1],c[2],c[3],c[4]
dt[i1+1] = {}
for m=1, #pal, 1 do
dt[i1+1][pal[m][4]+1] = db.getColorDistanceProx(r1,g1,b1,pal[m][1],pal[m][2],pal[m][3],rgbw[1],rgbw[2],rgbw[3],qualnorm, proxweight, briweight) -- pri/bri
end
end
--
 
statusmessage("MR: Analyzing Block 1..."); updatescreen(); if (waitbreak(0)==1) then return; end
r_analyzeBlock(dt,blocklist[1],qual,quant,rgbw,qualnorm,quantnorm,quantpow)
 
statusmessage("MR: Analyzing Blocks..."); updatescreen(); if (waitbreak(0)==1) then return; end
failsafe = 0
while (blocks < cnum and failsafe < 256) do
failsafe = failsafe + 1
maxdiff = -1
maxblock = -1
for n=1, blocks, 1 do
diff = blocklist[n].diff
if (diff > maxdiff) then maxdiff = diff; maxblock = n; end -- maxchan is stored as .chan in block
end
split = r_splitBlock(dt,blocklist,maxblock,qual,quant,rgbw,qualnorm,quantnorm,quantpow)
if (split == false) then messagebox("Only found "..blocks.." (24-bit) colors!"); break; end
blocks = #blocklist
statusmessage("MR: "..blocks); updatescreen(); if (waitbreak(0)==1) then return; end
end -- while
 
return r_blocks2Palette(blocklist,bits)
 
end
--
 
--
function r_blocks2Palette(blocklist,bits)
local n,r,g,b,c,pal,block,rgb,blen,M,dB,cB,rf,gf,bf
M = math
pal = {}
 
--bits = 1
dB = M.pow(2,8-bits)
cB = M.ceil(255 / (M.pow(2,bits) - 1))
 
for n=1, #blocklist, 1 do
block = blocklist[n]
r,g,b = 0,0,0
blen = #block
for c=1, blen, 1 do
rgb = block[c]
r = r + rgb[1]
g = g + rgb[2]
b = b + rgb[3]
end
 
rf = M.floor(M.min(255,M.max(0,M.floor(r/blen))) / dB) * cB
gf = M.floor(M.min(255,M.max(0,M.floor(g/blen))) / dB) * cB
bf = M.floor(M.min(255,M.max(0,M.floor(b/blen))) / dB) * cB
 
pal[n] = {rf, gf, bf} -- col is avg. of all colors in block
end -- blocklist
 
return pal
end
--
 
--
function r_analyzeBlock(dt,block,qual,quant,rgbw,qualnorm,quantnorm,quantpow)
local r,g,b,n,m,rmin,gmin,bmin,rmax,gmax,bmax,rdif,gdif,bdif,chan,d,median,diff
local len,Mm,Mx,rgb,kv,qu
local maxdist,dist,r1,g1,b1,r2,g2,b2,c1,c2,count
 
Mx,Mm = math.max, math.min
len = #block
 
rmin,gmin,bmin = 255,255,255
rmax,gmax,bmax = 0,0,0
maxdist,c1,c2,count = 0,-1,-1,0
 
for n=1, len, 1 do
rgb1 = block[n]
count = count + rgb1[5] -- pixelcount for color
for m=n+1, len, 1 do
rgb2 = block[m]
--dist = db.getColorDistanceProx(r1,g1,b1,r2,g2,b2,0.26,0.55,0.19,1.569, 0.1, 0.25) -- pri/bri
dist = dt[rgb1[4]+1][rgb2[4]+1]
 
if dist > maxdist then
maxdist = dist
c1 = rgb1[4]+1
c2 = rgb2[4]+1
end
end
end
-- quantity and quality are normalized to 256 (256 is the total of colors in the set for quantity)
-- Note that, regardless of forumla, quality (distance) must always be greater in any block than quantity (colors/pixels)
-- Coz a block may contain many of only 1 unique color, thus rendering it impossible to split if selected.
kv = 1
qu = 1
if (quant) then kv = math.pow(1 + count*quantnorm*quantpow, 0.5); end
if (qual) then qu = maxdist * qualnorm; end
diff = qu*(1-quantpow) + qu*kv
 
block.chan = -1
block.diff = diff
block.median = -1
block.c1 = c1
block.c2 = c2
 
return {diff,len}
 
end
--
 
function r_splitBlock(dt,blocklist,maxblock,qual,quant,rgbw,qualnorm,quantnorm,quantpow)
local n,cmax,median,blockA,blockB,len,cB,block,rgb,res
local c1,c2,dist1,dist2,medr,medg,medb,r1,g1,b1,r2,g2,b2,rgb1,rgb2
 
blockA,blockB = {},{}
block = blocklist[maxblock]
 
res = true
 
--chan = block.chan
--median = block.median
c1 = block.c1
c2 = block.c2
 
--rgb1 = block[c1]
--r1,g1,b1 = rgb1[1],rgb1[2],rgb1[3]
--rgb2 = block[c2]
--r2,g2,b2 = rgb2[1],rgb2[2],rgb2[3]
--medr = (r1+r2)/2
--medg = (g1+g2)/2
--medb = (b1+b2)/2
 
cB = blocklist[maxblock] -- maxblock starts at 1 when called so it should not hava a +1
len = #cB
 
if len < 2 then return false; end
 
for n=1, len, 1 do
rgb = cB[n]
dist1 = dt[rgb[4]+1][c1]
dist2 = dt[rgb[4]+1][c2]
 
if (dist1 <= dist2)
then table.insert(blockA,rgb);
end
 
if (dist1 > dist2) then
table.insert(blockB,rgb);
end
end
 
blocklist[maxblock] = blockA -- Can't be empty right?
r_analyzeBlock(dt,blocklist[maxblock],qual,quant,rgbw,qualnorm,quantnorm,quantpow)
 
if (#blockB > 0) then
table.insert(blocklist,blockB)
r_analyzeBlock(dt,blocklist[#blocklist],qual,quant,rgbw,qualnorm,quantnorm,quantpow) -- no -1 on blocklist
else
res = false
end
 
return res -- false = no split
end
 
------------ eof MEDIAN REDUX --------------------------
 
 
 
 
--
-- ... eof Custom Color / Palette functions ...
--
 
 
-- *****************************
-- *** Custom Draw functions ***
-- *****************************
 
--
function db.line(x1,y1,x2,y2,c) -- Coords should be integers or broken lines are possible
local n,st,m,xd,yd; m = math
st = m.max(1,m.abs(x2-x1),m.abs(y2-y1));
xd = (x2-x1) / st
yd = (y2-y1) / st
for n = 0, st, 1 do
putpicturepixel(m.floor(x1 + n*xd), m.floor(y1 + n*yd), c );
end
end
--
 
--
function db.lineTransp(x1,y1,x2,y2,c,amt) -- amt: 0-1, 1 = Full color
local n,st,m,x,y,r,g,b,r1,g1,b1,c2,org; m = math
org = 1 - amt
st = m.max(1,m.abs(x2-x1),m.abs(y2-y1));
for n = 0, st, 1 do
x = m.floor(x1+n*(x2-x1)/st)
y = m.floor(y1+n*(y2-y1)/st)
r,g,b = getcolor(getpicturepixel(x,y))
r1,g1,b1 = getcolor(c)
c2 = matchcolor(r1*amt+r*org, g1*amt+g*org, b1*amt+b*org)
putpicturepixel(x, y, c2 );
end
end
--
 
--
function db.drawBrushRectangle(x1,y1,w,h,c)
local x,y
for y = y1, y1+h-1, 1 do
for x = x1, x1+w-1, 1 do
putbrushpixel(x,y,c);
end
end
end
--
 
--
function db.drawRectangle(x1,y1,w,h,c)
local x,y
for y = y1, y1+h-1, 1 do
for x = x1, x1+w-1, 1 do
putpicturepixel(x,y,c);
end
end
end
--
 
--
function db.drawRectangleNeg(x1,y1,w,h,c)
local x,y,xs,ys
xs = db.sign(w)
ys = db.sign(h)
if xs == 0 then xs = 1; end
if ys == 0 then ys = 1; end
for y = y1, y1+h-1, ys do
for x = x1, x1+w-1, xs do
putpicturepixel(x,y,c);
end
end
end
--
 
--
function db.drawRectangleLine(x,y,w,h,c)
w = w-1
h = h-1
db.line(x,y,x+w,y,c)
db.line(x,y,x,y+h,c)
db.line(x,y+h,x+w,y+h,c)
db.line(x+w,y,x+w,y+h,c)
end
--
 
 
--
function db.drawRectangleMix(x1,y1,w,h,c1,c2)
local x,y,c,n
c = {c1,c2}
n = 0
for y = y1, y1+h-1, 1 do
n = n + 1
for x = x1, x1+w-1, 1 do
n = n + 1
putpicturepixel(x,y,c[n%2+1]);
end
end
end
--
 
--
function db.drawCircle(x1,y1,r,c) -- ok, lottsa weird adjustments here, can probably be optimized...
local x,y,d,r5,r25,r2,xr5,yr5
r5,r25,r2,xr5,yr5 = r+0.5,r-0.25,r*2, x1-r-0.5, y1-r-0.5
for y = 0, r2, 1 do
for x = 0, r2, 1 do
d = math.sqrt((x-r5)^2 + (y-r5)^2)
if d < r25 then putpicturepixel(x + xr5, y + yr5,c); end
end
end
end
--
 
--
function db.drawBrushCircle(x1,y1,r,c) -- ok, lottsa weird adjustments here, can probably be optimized...
local x,y,d
for y = 0, r*2, 1 do
for x = 0, r*2, 1 do
d = math.sqrt((x-r-0.5)^2 + (y-r-0.5)^2)
if d < r-0.25 then putbrushpixel(x1+x-r-0.5,y1+y-r-0.5,c); end
end
end
end
--
 
--
-- Rotation in degrees
-- Step is # of line segments (more is "better")
-- a & b are axis-radius
function db.ellipse2(x,y,a,b,stp,rot,col)
local n,m=math,rad,al,sa,ca,sb,cb,ox,oy,x1,y1,ast
m = math; rad = m.pi/180; ast = rad * 360/stp;
sb = m.sin(-rot * rad); cb = m.cos(-rot * rad)
for n = 0, stp, 1 do
ox = x1; oy = y1;
sa = m.sin(ast*n) * b; ca = m.cos(ast*n) * a
x1 = x + ca * cb - sa * sb
y1 = y + ca * sb + sa * cb
--if (n > 0) then db.line(ox,oy,x1,y1,col); end
if (n > 0) then drawline(ox,oy,x1,y1,col); end
end
end
--
 
 
 
--[[
var ER = 0.3
var DR = 0.15
 
ellipse(0.5*xx,0.5*yy,DR*xx,6,Math.PI*0)
 
function ellipse(x,y,r,stp,rot){
var n,deg=360,m=Math,rad=Math.PI/180,rn
var ox,oy,x1,y1,x2,y2,d1,r1 = ER * xx
for (n=0; n<=deg; n+=stp){
 
ox = x2; oy = y2, rn = rad * n
d1 = rn - rot
x1 = x + m.sin(d1) * r
y1 = y + m.cos(d1) * r
 
x2 = x1 + m.sin(-rn) * r1
y2 = y1 + m.cos(-rn) * r1
if (n > 0){ line_rgb(MX,[0,0,0],0,ox,oy,x2,y2) }
}
}
 
}
 
ellipse2(0.5*xx,0.5*yy,15,8,200,22,[0,0,0],0.5)
 
function ellipse2(x,y,a,b,stp,rot,rgb,transp){
var n,m=Math,rad=m.PI/180,al,sa,ca,sb,cb,ox,oy,x1,y1
sb = m.sin(-rot * rad); cb = m.cos(-rot * rad)
for (n=0; n<=stp; n++){
ox = x1; oy = y1; al = rad * 360/stp * n
sa = m.sin(al) * b; ca = m.cos(al) * a
x1 = x + ca * cb - sa * sb
y1 = y + ca * sb + sa * cb
if (n > 0){ line_rgb(MX,rgb,transp,ox,oy,x1,y1) }
}
}
 
 
]]
 
 
 
function db.obliqueCube(side,x,y,r,g,b,bri,cols)
local n,c,depth,x1,y1,x2,y2,f
 
asscols = false
if cols >= 0 and cols<250 then
asscols = true
c = cols; setcolor(cols,r,g,b); cols = cols + 1
cP50 = cols; q = bri*0.5; setcolor(cols,r+q,g+q,b+q); cols = cols + 1;
cP75 = cols; q = bri*0.75; setcolor(cols,r+q,g+q,b+q); cols = cols + 1;
cM50 = cols; q = -bri*0.5; setcolor(cols,r+q,g+q,b+q); cols = cols + 1;
cM100= cols; q = -bri; setcolor(cols,r+q,g+q,b+q); cols = cols + 1;
end
 
f = matchcolor
if asscols == false then
c = f(r,g,b)
cP50 = f(r+bri*0.5,g+bri*0.5,b+bri*0.5)
cP75 = f(r+bri*0.75,g+bri*0.75,b+bri*0.75)
cM50 = f(r-bri*0.5,g-bri*0.5,b-bri*0.5)
cM100 = f(r-bri,g-bri,b-bri)
end
 
 
depth = math.floor(side / 2)
 
for n = 0, depth-1, 1 do
db.line(x+side+n,y-1-n,x+side+n,y+side-n-1,cM50)
--drawline(x+side+n,y-1-n,x+side+n,y+side-n-1,cM50)
end
 
for n = 0, depth-1, 1 do
db.line(x+n,y-1-n,x+side+n-1,y-1-n,cP50)
--drawline(x+n,y-1-n,x+side+n-1,y-1-n,cP50)
end
 
-- /
--
--db.line(x+side,y-1,x+side+depth-1,y-depth,c)
 
-- Smoothing & Shade
 
--
-- /
--db.line(x+side,y+side-1,x+side+depth-1,y+side-depth,cM100)
 
--db.line(x,y,x+side-2,y,cP75)
--db.line(x,y,x,y+side-2,cP75)
 
db.drawRectangle(x,y,side,side,c)
 
return cols
 
end
 
 
function db.obliqueCubeBRI(side,x,y,r,g,b,bri,pallist,briweight,index_flag)
local n,c,depth,x1,y1,x2,y2
 
--f = db.getBestPalMatchHYBRID
c = db.getBestPalMatchHYBRID({r,g,b}, pallist, briweight, index_flag)
cP50 = db.getBestPalMatchHYBRID({r+bri*0.5,g+bri*0.5,b+bri*0.5}, pallist, briweight, index_flag)
cP75 = db.getBestPalMatchHYBRID({r+bri*0.75,g+bri*0.75,b+bri*0.75}, pallist, briweight, index_flag)
cM50 = db.getBestPalMatchHYBRID({r-bri*0.5,g-bri*0.5,b-bri*0.5}, pallist, briweight, index_flag)
cM100 = db.getBestPalMatchHYBRID({r-bri,g-bri,b-bri}, pallist, briweight, index_flag)
 
depth = math.floor(side / 2)
 
db.drawRectangle(x,y,side,side,c)
 
for n = 0, depth-1, 1 do
db.line(x+side+n,y-1-n,x+side+n,y+side-n-1,cM50)
--drawline(x+side+n,y-1-n,x+side+n,y+side-n-1,cM50)
end
 
for n = 0, depth-1, 1 do
db.line(x+n,y-1-n,x+side+n-1,y-1-n,cP50)
--drawline(x+n,y-1-n,x+side+n-1,y-1-n,cP50)
end
 
-- /
--
db.line(x+side,y-1,x+side+depth-1,y-depth,c)
--drawline(x+side,y-1,x+side+depth-1,y-depth,c)
 
 
-- Smoothing & Shade
 
--
-- /
--db.line(x+side,y+side-1,x+side+depth-1,y+side-depth,cM100)
 
--db.line(x,y,x+side-2,y,cP75)
--db.line(x,y,x,y+side-2,cP75)
 
 
end
 
 
--
function db.fillTriangle(p,fcol,lcol,fill,wire) -- p = list of 3 points
 
local n,x,y,x1,x2,y1,y2,xf,yf,len,mr
mr = math.floor
 
-- Convert to screen/matrix-coordinates
--if (mode == 'percent') then xf = xx / 100; yf = yy / 100; end
--if (mode == 'fraction') then xf = xx; yf = yy; end
--if (mode ~= 'absolute') then screenilizeTriangle(p,xf,yf); end
 
if (fill) then
local Ax,Ay,Bx,By,Cx,Cy,xd,a,b,yc,ABdy,BCdy,ABix,BCix,ACix
 
xd = {}
 
--sort(p,1) -- Find top and middle y-point
db.sorti(p,2)
 
Ay = p[1][2]; Ax = p[1][1]
By = p[2][2]; Bx = p[2][1]
Cy = p[3][2]; Cx = p[3][1]
 
ABdy = By - Ay
BCdy = Cy - By
ABix = (Bx - Ax) / ABdy
BCix = (Cx - Bx) / BCdy
ACix = (Cx - Ax) / (Cy - Ay)
 
a=1; b=2;
if (ACix < ABix) then a=2; b=1; end
for y = 0, ABdy-1, 1 do -- Upper -1
xd[a] = mr(Ax + ABix * y)
xd[b] = mr(Ax + ACix * y)
yc = y+Ay;
for x=xd[1], xd[2], 1 do
putpicturepixel(x,yc,fcol)
end
end
 
a=1; b=2;
if (BCix < ACix) then a=2; b=1; end
for y = 0, BCdy, 1 do -- Lower
xd[a] = mr(Cx - BCix * y);
xd[b] = mr(Cx - ACix * y)
yc = Cy-y;
for x = xd[1], xd[2], 1 do
putpicturepixel(x,yc,fcol)
end
end
 
end -- eof fill
if (wire) then
for n = 0, 2, 1 do -- Outline
x1 = p[n+1][1]; y1 = p[n+1][2]
x2 = p[1 + (n+1) % 3][1]; y2 = p[1 + (n+1) % 3][2]
--db.line(x1,y1,x2,y2,lcol)
drawline(x1,y1,x2,y2,lcol)
end
end
 
end -- eof fillTriangle
--
 
--
-- ... eof Custom Draw functions ...
--
 
 
-- ******************************
-- *** Filters & Convolutions ***
-- ******************************
 
 
function db.applyConvolution2Pic(convmx,divisor,bias,neg,amt)
local r,g,b,mx,my,cx,cy,mxh,myh,mp,rb,gb,bb,xx,yy,x,y,w,h,div,n1,n2,amtr,ro,go,bo
 
n1 = 1
n2 = bias
if neg == 1 then
n1 = -1
n2 = 255 + bias
end
amtr = 1 - amt
w, h = getpicturesize()
cy = #convmx
cx = #convmx[1]
mxh = math.floor(cx / 2) + 1
myh = math.floor(cy / 2) + 1
 
for y = 0, h-1, 1 do
for x = 0, w-1, 1 do
r,g,b = 0,0,0
ro,go,bo = getcolor(getbackuppixel(x,y))
div = divisor
for my = 1, cy, 1 do
for mx = 1, cx, 1 do
xp = mx-mxh
yp = my-myh
mp = convmx[my][mx]
xx = x + xp
yy = y + yp
if yy>=0 and yy<h and xx>=0 and xx<w then
rb,gb,bb = getcolor(getbackuppixel(xx,yy))
r = r + rb * mp
g = g + gb * mp
b = b + bb * mp
else div = div - mp -- Assumes divisor is the sum of the convolution matrix
end
end
end
r = ro*amtr + (n2 + (n1 * r) / div)*amt -- +bias
g = go*amtr + (n2 + (n1 * g) / div)*amt
b = bo*amtr + (n2 + (n1 * b) / div)*amt
putpicturepixel(x,y,matchcolor(r,g,b))
end;
updatescreen(); if (waitbreak(0)==1) then return; end
end;
 
end
 
--
-- ... eof Filters & Convolutions ...
--
 
 
 
-- *****************************
-- *** Fractals etc. ***
-- *****************************
 
-- Fractal Pattern V1.0 by Richard Fhager (mod allows for wrapping)
--
-- Pattern matrix example: {{1,1,1},{1,0,1},{1,1,1}}
--
function db.pattern(x,y,p,n,i) -- coord as fraction of 1, pattern, offset(0), iterations (1-15)
local px,py
py = #p
px = #p[1]
while ((p[1+math.abs(math.floor(y*py))%py][1+math.abs(math.floor(x*px))%px]) > 0 and n<i) do
x=x*px-math.floor(x*px);
y=y*py-math.floor(y*py);
n = n+1
end
return 1 - n/i;
end
--
 
--
function db.patternDec(x,y,p,n,i) -- coord as fraction of 1, pattern, offset(0), iterations (1-15)
local px,py,spfrac,nfrac,fx,fy
spfrac = 1
nfrac = 0
py = #p
px = #p[1]
while (spfrac > 0 and n<i) do
fy = math.floor(math.abs(y*py))%py
fx = math.floor(math.abs(x*px))%px
spfrac = p[fy+1][fx+1]
if (spfrac>0) then
x = x*px - fx
y = y*py - fy
nfrac = nfrac + spfrac
end
n = n+1
end
--return 1 - n/i;
return 1 - nfrac/i
end
--
 
 
--
function db.mandel(x,y,l,r,o,i) -- pos. as fraction of 1, left coord, right coord, y coord, iterations
 
local w,s,a,p,q,n,v,w
 
s=math.abs(r-l);
 
a = l + s*x;
p = a;
b = o - s*(y-0.5);
q = b;
n = 1;
v = 0;
w = 0;
 
while (v+w<4 and n<i) do n=n+1; v=p*p; w=q*q; q=2*p*q+b; p=v-w+a; end;
 
return n
end
--
 
--
-- ... eof Fractals etc. ...
--
 
 
-- ********************************************
-- *** Color Cube / Space, Custom Functions ***
-- ********************************************
--
-- SHADES (sha): 24bit colors is too complex so we operate with less shades/bits/colors.
-- 16 shades = 12bit = 16*16*16 = 4096 colors (or cubic-elements)
-- 32 shades = 15bit = 32*32*32 = 32768 colors
 
--
-- data: {color available flag, 0 (gravity/distance, calculated, init as zero)}
--
function db.initColorCube(sha,data)
local ary,z,y,x,n
ary = {}
for z = 0, sha-1, 1 do
ary[z+1] = {}
for y = 0, sha-1, 1 do
ary[z+1][y+1] = {}
if data ~= nil then
for x = 0, sha-1, 1 do
-- This is silly stupid, if you know how to assign one array to another (no ref), plz help!
-- i.e. how to: data = {false,0}; myArray[z][y][x] = data.
ary[z+1][y+1][x+1] = {}
for n = 1, #data, 1 do
ary[z+1][y+1][x+1][n] = data[n]
end
end
end
end
end
return ary
end
--
 
--
function db.findVoid(cube,sha) -- void is point with longest distance to closest color
local weakest,weak_i,x,y,z,c,w
weakest = -1
weak_i = {-1,-1,-1}
for z = 0, sha-1, 1 do
for y = 0, sha-1, 1 do
for x = 0, sha-1, 1 do
c = cube[z+1][y+1][x+1]
if c[1] == true then
w = c[2]
if w > weakest then weakest = w; weak_i = {z,y,x}; end
end
end;end;end
return weak_i[1],weak_i[2],weak_i[3]
end
--
 
--
--
-- Nearest color version: void is selected by the point that has the greatest distance
-- to the nearest color. Higher value means greater void.
--
function db.addColor2Cube(cube,sha,r,g,b,rw,gw,bw)
local star,x,y,z,d,rd,gd,bd,cu1,cu2
star = 0
cube[r+1][g+1][b+1] = {false, star}
for z = 0, sha-1, 1 do
rd = (rw*(z-r))^2
cu2 = cube[z+1]
for y = 0, sha-1, 1 do
gd = (gw*(y-g))^2
cu1 = cu2[y+1]
for x = 0, sha-1, 1 do
d = rd + gd + (bw*(x-b))^2
 
--cube[z+1][y+1][x+1][2] = math.min(d, cube[z+1][y+1][x+1][2]) -- Don't add, use nearest color
 
cu1[x+1][2] = math.min(d, cu1[x+1][2])
 
end;end;end
end
--
 
-- Should be same as original, but not 100% verified. Using a rgb+1 trick to speed up handling
--
function db.addColor2Cube_test(cube,sha,r,g,b,rw,gw,bw)
local star,x,y,z,d,rd,gd,bd,cu1,cu2
star = 0
r = r+1; g = g+1; b = b+1
cube[r][g][b] = {false, star}
for z = 1, sha, 1 do
rd = (rw*(z-r))^2
cu2 = cube[z]
for y = 1, sha, 1 do
gd = (gw*(y-g))^2
cu1 = cu2[y]
for x = 1, sha, 1 do
cu1[x][2] = math.min(rd+gd+(bw*(x-b))^2, cu1[x][2])
end;end;end
end
--
 
 
 
-- Create new allowed colorlines in colorspace (ramps from which colors can be picked)
function db.enableRangeColorsInCube(cube,sha,r1,g1,b1,r2,g2,b2)
 
local div,r,g,b,n,rs,gs,bs
div = 256 / sha
rs = (r2 - r1) / sha / div
gs = (g2 - g1) / sha / div
bs = (b2 - b1) / sha / div
 
for n = 0, sha-1, 1 do
 
r = math.floor(r1/div + rs * n)
g = math.floor(g1/div + gs * n)
b = math.floor(b1/div + bs * n)
 
cube[r+1][g+1][b+1][1] = true
 
end
end
--
 
 
function db.colorCigarr(shades,radius,fill_flag)
local s,rad,radsq,step,shalf,bas,cols,found,x,y,z,bri,con,d,n
radius = radius / 100
step = math.floor(255 / (shades-1))
shalf = math.floor(shades / 2)
s = shades - 1
rad = math.floor(shades / 2 * radius)
radsq = rad^2
 
bas = 0
cols = {}
found = 0
 
for z = 0, s, 1 do
for y = 0, s, 1 do
for x = 0, s, 1 do
 
--0.26,0.55,0.19
bri = (x + y + z ) / 3
--bri = math.sqrt(((x*0.26)^2 + (y*0.55)^2 + (z*0.19)^2)) * 1.5609
con = math.floor((shades - math.abs(bri - shalf)*2) * radius)
 
d = math.floor(math.sqrt((bri-x)^2 + (bri-y)^2 + (bri-z)^2))
--d = math.floor(math.sqrt(((bri-x)*0.26)^2 + ((bri-y)*0.55)^2 + ((bri-z)*0.19)^2)) * 1.5609
 
-- Filled cigarr: Less or Equal, cigarr shell: Equal
if d == con or (d < con and fill_flag) then
found = found + 1
r = bas + x * step
g = bas + y * step
b = bas + z * step
cols[found] = {r,g,b}
end
 
end; end; end
 
--messagebox("Colors found: "..found.."\n\n".."Run AnalyzePalette to examine")
 
for n = 0, 255, 1 do
if n < found then
c = cols[n+1]
setcolor(n,c[1],c[2],c[3])
else
setcolor(n,0,0,0)
end
end
end -- eof colorcigarr
 
 
--
-- ... eof Color Cube ...
--
 
 
 
-- COLORMIX --
--
-- Returns a list of mixcolors palette entries, that are ranked by by quality & usefulness
--
-- This whole junk my partly locked on 16 shades (4096 colors/ 12bit palette precision) so don't use anything else...
--
--
function db.colormixAnalysis(sha,spare_flag,cust_dist) -- Interface
local shades,pallist,ilist,custom_max_distance
 
shades = sha -- 16 is good
--messagebox(shades)
 
custom_max_distance = -1
if cust_dist ~= null then
custom_max_distance = cust_dist -- in %
end
 
if spare_flag == true then -- No shades here for now
--pallist = db.makePalListShadeSPARE(256,shades) -- 16 shades so Colorcube processes is possible
pallist = db.makeSparePalList(256)
pallist = db.fixPalette(pallist,0) -- Remove doubles, No need to sort?
ilist = db.makeIndexList(pallist, -1) -- -1, use list order as index
else
pallist = db.makePalListShade(256,shades) -- 16 shades so Colorcube processes is possible
pallist = db.fixPalette(pallist,0) -- Remove doubles, No need to sort?
ilist = db.makeIndexList(pallist, -1) -- -1, use list order as index
end
 
if shades > 0 then
return db.colormixAnalysisEXT(shades,pallist,ilist,custom_max_distance) -- max distance in %
end
if shades == -1 then
return db.colormixAnalysisEXTnoshade(pallist,ilist,custom_max_distance) -- max distance in %
end
end
--
--
function db.colormixAnalysisEXT(SHADES,pallist,ilist,custom_max_distance) -- Shades, most number of mixes returned
local n,m,c1,c2,pairs,cube,rm,gm,bm
local mix,total,found,dist,void,ideal,mini,maxi,bestmix,bestscore
--messagebox("will now make pairs")
 
pairs = db.pairsFromList(ilist,0) -- 0 for unique pairs only, pairs are entries in pallist
 
--messagebox(#pairs.." will now add colors to cube")
 
cube = db.initColorCube(SHADES,{true,9999})
for n = 1, #pallist, 1 do
c1 = pallist[n]
db.addColor2Cube_test(cube,SHADES,c1[1],c1[2],c1[3],0.26,0.55,0.19)
end
 
-- these values are adjusted for a 12bit palette (0-15) and perceptual weight where r+g+b = 1.0
-- Ideal distance = 2.5 Green steps = 1.375
-- Minimum distance = 1 Green step = 0.55
 
--messagebox("colorcube done")
 
VACT = 1
DACT = 1
 
total = 9.56 -- Max distance possible with 16 shades
ideal = 0.45 -- 1 step = 0.637
mini = 0.35
maxi = ideal + (total - ideal) / math.max(1, #pallist / 16)
if custom_max_distance ~= -1 then
maxi = total * (custom_max_distance / 100)
end
mix = {}
--mix[1] = {9e99,0,0,9e99,0,0,0}
bestmix = -1
bestscore = 9e99
found = 0
for n = 1, #pairs, 1 do
 
c1 = pallist[pairs[n][1]]
c2 = pallist[pairs[n][2]]
--0.26,0.55,0.19
dist = db.getColorDistance_weight(c1[1],c1[2],c1[3],c2[1],c2[2],c2[3],0.26,0.55,0.19) -- Not normalized
 
rm = math.floor((c1[1]+c2[1])/2)
gm = math.floor((c1[2]+c2[2])/2)
bm = math.floor((c1[3]+c2[3])/2)
 
-- Mix color adjustment (perhaps less than perfect, but probably good enough)
mixbri = db.getBrightness(rm,gm,bm)
truebri = math.sqrt((db.getBrightness(c1[1],c1[2],c1[3])^2 + db.getBrightness(c2[1],c2[2],c2[3])^2) / 2)
diff = truebri - mixbri
rm = math.max(0,math.min(15,math.floor(rm + diff)))
gm = math.max(0,math.min(15,math.floor(gm + diff)))
bm = math.max(0,math.min(15,math.floor(bm + diff)))
newbri = db.getBrightness(rm,gm,bm)
delta = math.abs(newbri - truebri)
--if delta > 0.9 then
-- messagebox(pallist[pairs[n][1]][4]..", "..pallist[pairs[n][2]][4].." delta = "..delta)
--end
--
 
--rm = math.floor(math.sqrt((c1[1]^2 + c2[1]^2) / 2))
--gm = math.floor(math.sqrt((c1[2]^2 + c2[2]^2) / 2))
--bm = math.floor(math.sqrt((c1[3]^2 + c2[3]^2) / 2))
 
void = cube[rm+1][gm+1][bm+1][2]
 
if dist >= mini and dist <= maxi then
found = found + 1
score = ((1+DACT*(dist - ideal)^2) / (1+void*VACT)) -- Lowest is best
mix[found] = {score,pallist[pairs[n][1]][4],pallist[pairs[n][2]][4],dist,rm*SHADES,gm*SHADES,bm*SHADES,c1[1]*SHADES,c1[2]*SHADES,c1[3]*SHADES,c2[1]*SHADES,c2[2]*SHADES,c2[3]*SHADES} -- mix holds palette entry
if score < bestscore then bestscore = score; bestmix = found; end
end
 
end
 
 
if true == false then
-- 2nd pass, add bestmix to colorspace. This reduces many similar mixes.
m = mix[bestmix]
db.addColor2Cube(cube,SHADES,m[5],m[6],m[7],0.26,0.55,0.19)
for n = 1, #mix, 1 do
if n ~= bestmix then
m = mix[n]
dist = m[4]
void = cube[m[5]+1][m[6]+1][m[7]+1][2]
score = ((1+DACT*(dist - ideal)^2) / (1+void*VACT))
m[1] = score
end
end
end
 
c1,c2 = -1,-1
if found > 0 then
db.sorti(mix,1)
best = mix[1]
c1 = best[2]
c2 = best[3]
end
 
--return found,c1,c2
return mix,found,c1,c2
end
--
 
 
--
-- Mixcolor without colorcube - no scoring or sorting, 24bit colors, faster...
--
function db.colormixAnalysisEXTnoshade(pallist,ilist,custom_max_distance)
local n,m,c1,c2,pairs,cube,rm,gm,bm
local mix,total,found,dist,void,ideal,mini,maxi,bestmix,bestscore
 
pairs = db.pairsFromList(ilist,0) -- 0 for unique pairs only, pairs are entries in pallist
 
total = 162.53 -- Max distance possible with 24-bit palette ad Dawn3.0 color weights 162.53
ideal = 0
mini = 0
maxi = ideal + (total - ideal) / math.max(1, #pallist / 16)
 
if custom_max_distance ~= -1 then
maxi = total * (custom_max_distance / 100)
end
 
statusmessage("Mixcol Analysis ("..#pairs.." pairs) ");
updatescreen(); if (waitbreak(0)==1) then return; end
 
mix = {}
found = 0
for n = 1, #pairs, 1 do
c1 = pallist[pairs[n][1]]
c2 = pallist[pairs[n][2]]
--0.26,0.55,0.19
dist = db.getColorDistance_weight(c1[1],c1[2],c1[3],c2[1],c2[2],c2[3],0.26,0.55,0.19) -- Not normalized
 
rm = math.floor((c1[1]+c2[1])/2)
gm = math.floor((c1[2]+c2[2])/2)
bm = math.floor((c1[3]+c2[3])/2)
 
-- Mix color adjustment
mixbri = db.getBrightness(rm,gm,bm)
truebri = math.sqrt((db.getBrightness(c1[1],c1[2],c1[3])^2 + db.getBrightness(c2[1],c2[2],c2[3])^2) / 2)
diff = truebri - mixbri
rm = math.max(0,math.min(255,math.floor(rm + diff)))
gm = math.max(0,math.min(255,math.floor(gm + diff)))
bm = math.max(0,math.min(255,math.floor(bm + diff)))
newbri = db.getBrightness(rm,gm,bm)
delta = math.abs(newbri - truebri)
--if delta > 0.9 then
-- messagebox(pallist[pairs[n][1]][4]..", "..pallist[pairs[n][2]][4].." delta = "..delta)
--end
--
 
if dist >= mini and dist <= maxi then
found = found + 1
score = 1
mix[found] = {score,pallist[pairs[n][1]][4],pallist[pairs[n][2]][4],dist,rm,gm,bm,c1[1],c1[2],c1[3],c2[1],c2[2],c2[3]} -- mix holds palette entry
end
 
end
 
--messagebox(#mix)
 
return mix,found,-1,-1
end
--
 
 
 
-- Fuse a palettelist into an extended mix-anlysis list
function db.fusePALandMIX(pal,mix,max_score,max_dist)
local n,c,mixlist,tot,score,dist,c1,c2,rm,gm,bm
 
mixlist = {}
tot = 0
 
-- {r,g,b,n}
for n = 1, #pal, 1 do
tot = tot + 1
c = pal[n]
mixlist[tot] = {0,c[4],c[4],0,c[1],c[2],c[3],c[1],c[2],c[3],c[1],c[2],c[3]}
end
 
-- {score,col#1,col#2,dist,rm,gm,bm} low score is best
for n = 1, #mix, 1 do
score = mix[n][1]
dist = mix[n][4]
if score <= max_score and dist <= max_dist then
tot = tot + 1
mixlist[tot] = mix[n]
end
end
 
return mixlist
end
--
 
 
-- ********************************************
-- *** L-system (fractal curves & "plants") ***
-- ********************************************
--
 
--
function db.Lsys_makeData(a)
local n,i; i = {}
for n = 1, #a, 1 do i[a[n][2]] = a[n]; end
return i
end
--
 
--
function db.Lsys_makeSet(seed,iter,data)
local s,n,i,nset,set
set = seed
for n = 1, iter, 1 do
nset = ''
for i = 1, #set, 1 do
s = string.sub(set,i,i)
nset = nset..data[s][3]
end
set = nset
end
return set
end
--
 
function db.Lsys_draw(set,data,cx,cy,size,rot,rgb,rng,transp, speed)
local p,M,DEG,l,n,d,i,v,q,c,tx,ty,posx,posy,dval,col,w,h,s,cl,count
 
if speed == nil then speed = 50; end -- speed is drawing operations per update
 
function ang(d) return (d % 360 + 360) * DEG; end
w,h = getpicturesize()
 
p = 0
M = math
DEG = math.pi/180
l = #set
 
posx={}; posy={}; dval={}
 
if (rgb == null) then rgb = {0,0,0}; end
if (transp == null) then transp = 0; end
col = db.newArrayMerge(rgb,{})
q = 255 / l
 
count = 0
for n = 1, l, 1 do
s = string.sub(set,n,n)
d = data[s]
i = d[1]
v = d[4]
 
--messagebox(i)
 
if (i == 'Left') then rot = rot - v; end
if (i == 'Right') then rot = rot + v; end
if (i == 'Save') then p=p+1; posx[p] = cx; posy[p] = cy; dval[p] = rot; end
if (i == 'Load') then cx = posx[p]; cy = posy[p]; rot = dval[p]; p=p-1; end
 
if (i == 'Draw') then
tx = cx + M.sin(ang(rot)) * size
ty = cy + -M.cos(ang(rot)) * size
for c = 1, 3, 1 do
if (rng[c] > 0) then col[c] = rgb[c] + (n * q) * rng[c]; end
if (rng[c] < 0) then col[c] = rgb[c] + (n * q) * rng[c]; end
end
 
cl = matchcolor(col[1],col[2],col[3])
--putpicturepixel(cx*w,cy*h,cl);
--db.line(cx*w,cy*h,tx*w,ty*h,cl)
db.lineTransp(cx*w,cy*h,tx*w,ty*h,cl,transp)
cx = tx; cy = ty
end
count = count + 1
if count == speed then count = 0; updatescreen(); if (waitbreak(0)==1) then return end; end
end
 
return {cx,cy,rot}
end -- draw
 
 
--
-- eof L-system
--
---------------------------------------------------------------------------------------
 
 
 
-- ********************************************
-- *** COMPLEX SPECIAL FUNCTIONS ***
-- ********************************************
--
 
---------------------------------------------------------------------------------------
--
-- Render engine for mathscenes (Full Floyd-Steinberg dither etc)
--
function db.fsrender(f,pal,ditherprc,xdith,ydith,percep,xonly, ord_bri,ord_hue,bri_change,hue_change,BRIWEIGHT, wd,ht,ofx,ofy) -- f is function
 
local w,h,i,j,c,x,y,r,g,b,d,fl,v,v1,v2,vt,vt1,vt2,dither,m,mathfunc,dpow,fsdiv,ord,d1a,d1b,briweight
local d1,d2,o1,o2,ox,oy
 
-- percep is no longer used, matchcolor2 is always active, but the code is kept if there's ever a need to
-- study the effect of perceptual colorspaces versus matchcolor
 
if ord_bri == null then ord_bri = 0; end
if ord_hue == null then ord_hue = 0; end
if bri_change == null then bri_change = 0; end
if hue_change == null then hue_change = 0; end
if BRIWEIGHT == null then BRIWEIGHT = 0; end
 
briweight = BRIWEIGHT / 100
 
ord = {{0,4,1,5},
{6,2,7,3},
{1,5,0,4},
{7,3,6,2}}
 
--i = ((ord[y % 4 + 1][x % 4 + 1])*28.444 - 99.55556)/100 * 16
function hue(r,g,b,deg)
local i,brin,diff,brio,r2,g2,b2
r2,g2,b2 = db.shiftHUE(r,g,b,deg)
brio = db.getBrightness(r,g,b)
for i = 0, 5, 1 do -- 6 iterations, fairly strict brightness preservation
brin = db.getBrightness(r2,g2,b2)
diff = brin - brio
r2,g2,b2 = db.rgbcap(r2-diff, g2-diff, b2-diff, 255,0)
end
return r2,g2,b2
end
 
 
 
fsdiv = 16
if xonly == 1 then fsdiv = 7; end -- Only horizontal dither
 
dither = 0; if ditherprc > 0 then dither = 1; end
 
-- When using standard error-diffusion brightness-matching is not really compatible
--matchfunc = matchcolor2
--if dither == 1 then matchfunc = matchcolor; end
 
dpow = ditherprc / 100
 
 
if wd == null then
w,h = getpicturesize()
else w = wd; h = ht
end
 
if ofx == null then
ox,oy = 0,0
else ox = ofx; oy = ofy
end
 
 
function cap(v)
return math.min(255,math.max(0,v))
end
 
 
 
--
fl = {}
fl[1] = {}
fl[2] = {}
i = 1
j = 2
--
 
-- Read the first 2 lines
v1 = ydith/2 + 0%2 * -ydith
v2 = ydith/2 + 1%2 * -ydith
for x = 0, w - 1, 1 do
d1a,d1b = 0,0
if ord_bri > 0 then
o1 = ord[0 % 4 + 1][x % 4 + 1]
d1a = (o1*28.444 - 99.55556)/100 * ord_bri
o2 = ord[1 % 4 + 1][(x+2) % 4 + 1] -- +2 To get it in right sequence for some reason
d1b = (o2*28.444 - 99.55556)/100 * ord_bri
end
-- We skip Hue-ordering for now
vt1 = v1 + xdith/2 + (x+math.floor(0/2))%2 * -xdith + d1a
vt2 = v2 + xdith/2 + (x+math.floor(1))%2 * -xdith + d1b -- Ok, not sure why 1/2 doesn't make for a nice pattern so we just use 1
r,g,b = f(x, 0, w, h)
fl[i][x] = {cap(r+vt1),cap(g+vt1),cap(b+vt1)}
r,g,b = f(x, 1, w, h)
fl[j][x] = {cap(r+vt2),cap(g+vt2),cap(b+vt2)}
end
 
for y = 0, h-1, 1 do
for x = 0, w-1, 1 do
 
o = fl[i][x]
r = o[1] + bri_change
g = o[2] + bri_change
b = o[3] + bri_change
 
if hue_change ~= 0 then
r,g,b = hue(r,g,b,hue_change)
end
 
--if percep == 0 then c = matchfunc(r,g,b); end
--if percep == 1 then
-- --c = db.getBestPalMatchHYBRID({r,g,b},pal,0,true)
--c = matchcolor2(r,g,b,briweight)
--end
 
c = matchcolor2(r,g,b,briweight)
 
putpicturepixel(x+ox,y+oy,c)
 
if dither == 1 then
if x>1 and x<w-1 and y<h-1 then
rn,gn,bn = getcolor(c)
re = ((r - rn) / fsdiv) * dpow
ge = ((g - gn) / fsdiv) * dpow
be = ((b - bn) / fsdiv) * dpow
o = fl[i][x+1]; r,g,b = o[1],o[2],o[3]
fl[i][x+1] = {cap(r+re*7), cap(g+ge*7), cap(b+be*7)}
if xonly ~= 1 then
o = fl[j][x]; r,g,b = o[1],o[2],o[3]
fl[j][x] = {cap(r+re*5), cap(g+ge*5), cap(b+be*5)}
o = fl[j][x-1]; r,g,b = o[1],o[2],o[3]
fl[j][x-1] = {cap(r+re*3), cap(g+ge*3), cap(b+be*3)}
o = fl[j][x+1]; r,g,b = o[1],o[2],o[3]
fl[j][x+1] = {cap(r+re), cap(g+ge), cap(b+be)}
end
end
end
 
end
 
vt = 0
v = ydith/2 + y%2 * -ydith
-- Flip ED lines and read the nextline
i,j = j,i
for x = 0, w - 1, 1 do
 
d1,d2 = 0,0
if ord_bri > 0 then
o = ord[y % 4 + 1][x % 4 + 1]
d1 = (o*28.444 - 99.55556)/100 * ord_bri
end
vt = v + xdith/2 + (x+math.floor(y/2))%2 * -xdith + d1
r,g,b = f(x, y+2, w, h)
 
if ord_hue > 0 then
o = ord[y % 4 + 1][x % 4 + 1]
d2 = (((o + 3.5) % 7) / 7 - 0.5) * ord_hue
r,g,b = hue(r,g,b,d2)
end
fl[j][x] = {cap(r+vt),cap(g+vt),cap(b+vt)}
end
updatescreen(); if (waitbreak(0)==1) then return; end
end
 
 
end
-------------------------------------------------------------------------------
 
--
-- ROTATE Image or Brush
--
-- target: 1 = Brush, 2 = Picture, 3 = Brush-to-Picture
-- rot: Rotation in degrees
-- mode: 1 = Simple, 2 = Cosine Interpolation, 2 = BiLinear Interpolation
-- spritemode: 0 = Off, 1 = On (Only match adjacent colors, use with Bilinear-Ip. for good result)
-- resize: 0 = No, 1 = Yes (Resize Image/Brush to fit all gfx, otherwise clip)
-- update: 0 = No, 1 = Yes (Update screen while drawing)
-- xoffset: For use with Brush-to-Picture operations
-- yoffset: For use with Brush-to-Picture operations
--
function db.doRotation(target,rot,mode,spritemode,resize,update, xoffset,yoffset)
 
local trg,f,w,h,x,y,r,g,b,c,hub_x,hub_y,x1,y1,x2,y2,x3,y3,x4,y4,dX,dY,dXs,dYs,ox,oy,mx,my,xp,yp,pal,func
 
function donothing(n)
end
 
func = {
{getsize=getbrushsize, setsize=setbrushsize, clear=donothing, get=getbrushbackuppixel, put=putbrushpixel},
{getsize=getpicturesize, setsize=setpicturesize, clear=clearpicture, get=getbackuppixel, put=putpicturepixel},
{getsize=getbrushsize, setsize=donothing, clear=donothing, get=getbrushbackuppixel, put=putpicturepixel}
}
trg = func[target]
 
--
function bilinear(ox,oy,w,h,func,mode)
local xp1,xp2,yp1,yp2,r1,r2,r3,r4,g1,g2,g3,g4,b1,b2,b3,b4,r,g,b, c1,c2,c3,c4,pal,adjx,adjy
xp2 = ox - math.floor(ox)
yp2 = oy - math.floor(oy)
 
if mode == 1 then -- Cosinus curve (rather than linear), slightly sharper result (probably same as Photoshop)
xp2 = 1 - (math.cos(xp2 * math.pi) + 1)/2
yp2 = 1 - (math.cos(yp2 * math.pi) + 1)/2
end
 
xp1 = 1 - xp2
yp1 = 1 - yp2
 
c1 = func(math.floor(ox),math.floor(oy));
c2 = func(math.ceil(ox),math.floor(oy));
c3 = func(math.floor(ox),math.ceil(oy));
c4 = func(math.ceil(ox),math.ceil(oy));
 
r1,g1,b1 = getcolor(c1);
r2,g2,b2 = getcolor(c2);
r3,g3,b3 = getcolor(c3);
r4,g4,b4 = getcolor(c4);
pal = {{r1,g1,b1,c1},{r2,g2,b2,c2},{r3,g3,b3,c3},{r4,g4,b4,c4}} -- for SpriteMode ColorMatching
 
r = (r1*xp1 + r2*xp2)*yp1 + (r3*xp1 + r4*xp2)*yp2;
g = (g1*xp1 + g2*xp2)*yp1 + (g3*xp1 + g4*xp2)*yp2;
b = (b1*xp1 + b2*xp2)*yp1 + (b3*xp1 + b4*xp2)*yp2;
 
return r,g,b, pal
end
--
 
f = db.rotationFrac
w,h = trg.getsize()
hub_x = w / 2 - 0.5 -- Rotates 90,180 perfectly, not 45
hub_y = h / 2 - 0.5
--hub_x = w / 2
--hub_y = h / 2
x1,y1 = f (-rot,hub_x,hub_y,0,0) -- Rot is negative coz we read destination and write to source
x2,y2 = f (-rot,hub_x,hub_y,w-1,0)
x3,y3 = f (-rot,hub_x,hub_y,0,h-1)
x4,y4 = f (-rot,hub_x,hub_y,w-1,h-1)
dX = (x2 - x1) / w
dY = (y2 - y1) / w
dXs = (x4 - x2) / h
dYs = (y3 - y1) / h
 
adjx,adjy = 0,0
ox,oy = 0,0
if resize == 1 then
mx = math.ceil(math.max(math.abs(x1-hub_x),math.abs(x3-hub_x))) * 2 + 2
my = math.ceil(math.max(math.abs(y1-hub_y),math.abs(y3-hub_y))) * 2 + 2
if target == 3 then -- Center gfx at Brush-to-Picture
adjx = -mx/2
adjy = -my/2
end
ox = (mx - w) / 2
oy = (my - h) / 2
trg.setsize(mx,my)
end
 
trg.clear(0)
 
for y = -oy, h-1+oy, 1 do
RE,GE,BE = 0,0,0
for x = -ox, w-1+ox, 1 do
xp = x1 + dX * x + dXs * y
yp = y1 + dY * x + dYs * y
 
if mode == 2 or mode == 3 then
r,g,b,pal = bilinear(xp,yp,w,h,trg.get, mode_co)
if spritemode == 1 then
c = db.getBestPalMatchHYBRID({r+RE,g+GE,b+BE},pal,0.65,true) -- Brightness do very little in general with 4 set colors
else c = matchcolor2(r+RE,g+GE,b+BE)
end
else c = trg.get(xp,yp)
end
 
--rn,gn,bn = getcolor(c)
--RE = (r - rn)*0.5
--GE = (g - gn)*0.5
--BE = (b - bn)*0.5
 
trg.put(x+ox+xoffset+adjx,y+oy+yoffset+adjy, c)
end
if update == 1 then
statusmessage("Working... %"..math.floor(((y+oy) / (h-1+2*oy))*100))
updatescreen(); if (waitbreak(0)==1) then return; end
end
end
 
end; -- doRotation
 
-------------------------------------------------------------------------------
 
--
-- PARTICLE v1.0
--
-- Draw Sphere or Disc to any target with gradients that may fade to background
--
-- type: "sphere" - volmetric planet-like disc
-- "disc" - plain disc
-- mode: "blend" - mix graphics with background color
-- "add" - add graphics to background color
-- wd,ht: - Max Width/Height of drawing area, i.e. screen size (needed if drawing to an array-buffer)
-- sx,sy: - drawing coordinates (center)
-- xrad,yrad: - x & y radii
-- rgba1: - rgb+alpha array of center color: {r,g,b,a}, alpha is 0..1 where 1 is no transparency, Extreme rgb-values allowed
-- rgba2: - rgb+alpha array of edge color: {r,g,b,a}, alpha is 0..1 where 1 is no transparency, Extreme rgb-values allowed
-- update_flag: - Display rendering option (and add break feature)
-- f_get: - Get pixel function: use getpicturepixel if reading from image (set null for image default)
-- f_put: - Put pixel function: use putpicturepixel if drawing to image (set null for image default)
-- f_recur: - Optional custom control-function for recursion (set null if not used)
-- recur_count - Recursion depth counter, for use in combination with a custom function (f_recur), 0 as default
--
-- Ex: particle("sphere","add", w,h, w/2,h/2, 40,40, {500,400,255, 0.8},{0,-150,-175, 0.0}, true, null, null, null, 0)
--
function db.particle(type,mode,wd,ht,sx,sy,xrad,yrad,rgba1,rgba2, update_flag, f_get, f_put, f_recur, recur_count)
 
local x,y,rev,dix,diy,r3,g3,b3,px,py,alpha,ralpha,add,q,rgb,rgb1,rgb2,rgb3,n,def_get,def_put
 
function def_get(x,y)
local r,g,b
r,g,b = getcolor(getpicturepixel(x,y));
return {r,g,b}
end
function def_put(x,y,r,g,b) putpicturepixel(x,y, matchcolor2(r,g,b,0.65)); end
if f_get == null then f_get = def_get; end
if f_put == null then f_put = def_put; end
 
q = {[true] = 1, [false] = 0}
 
rgb,rgb1,rgb2 = {},{},{}
 
if mode == 'blend' then
add = 1
end
 
if mode == 'add' then
add = 0
end
 
dix = xrad*2
diy = yrad*2
 
for y = 0, diy, 1 do
py = sy+y-yrad; oy = y / diy;
if (py >= 0 and py < ht) then
 
for x = 0, dix, 1 do
px = sx+x-xrad; ox = x / dix;
if (px >= 0 and px < wd) then
 
if type == 'sphere' then -- Sphere
a = math.sqrt(math.max(0,0.25 - ((0.5-ox)^2+(0.5-oy)^2))) * 2
end
if type == 'disc' then -- Disc
a = 1-math.sqrt((0.5-ox)^2+(0.5-oy)^2)*2
end
 
if a>0 then
 
rev = 1-a
rgb3 = f_get(px,py)
alpha = rgba1[4] * a + rgba2[4] * rev
ralpha = 1 - alpha * add
 
for n = 1, 3, 1 do
rgb1[n] = q[rgba1[n]==-1]*rgb3[n] + q[rgba1[n]~=-1]*rgba1[n] -- Fade from background?
rgb2[n] = q[rgba2[n]==-1]*rgb3[n] + q[rgba2[n]~=-1]*rgba2[n] -- Fade to background?
rgb[n] = (rgb1[n] * a + rgb2[n] * rev) * alpha + rgb3[n] * ralpha
end
 
f_put(px, py, rgb[1],rgb[2],rgb[3]);
end
 
end -- if x is good
end -- x
if update_flag then updatescreen(); if (waitbreak(0)==1) then return; end; end
end -- if y is good
end -- y
 
if f_recur ~= null then -- recursion
f_recur(type,mode,wd,ht,sx,sy,xrad,yrad,rgba1,rgba2, update_flag, f_get, f_put, f_recur, recur_count);
updatescreen(); if (waitbreak(0)==1) then return; end;
end
 
end
-- eof PARTICLE
 
 
--
-- MedianCut a larger palette-list from a MathScene to produce a high-quality BriSorted palette for the final render/colormatching
--
function db.makeSamplePal(w,h,colors,frend)
local n,x,y,r,g,b,pal
n,pal = 0,{}
for y = 0, h, math.ceil(h/63) do
for x = 0, w, math.ceil(w/63) do
r,g,b = frend(x,y,w,h)
n = n+1
r,g,b = db.rgbcapInt(r,g,b,255,0)
pal[n] = {r,g,b,0}
end;end
return db.fixPalette(db.medianCut(pal, colors, true, false, {0.26,0.55,0.19}, 8, 0),1) -- pal, cols, qual, quant, weights, bits, quantpower
end
--
 
--
-- Backdrop/Gradient Render (May be written to a matrix for rendering with db.fsrender)
--
function db.backdrop(p0,p1,p2,p3,fput,ip_mode) -- points:{x,y,r,g,b}, IpMode "linear" is default
 
local x,y,ox,oy,xr,yr,r,g,b,ax,ay,w,h
 
ax,ay = p0[1],p0[2]
 
w = p1[1] - p0[1]
h = p2[2] - p0[2]
 
for y = 0, h, 1 do -- +1 to fill screen with FS-render
 
oy = y/h
if ip_mode == "cosine" then oy = 1 - (math.cos(oy * math.pi) + 1)/2; end
yr = 1 - oy
 
for x = 0, w, 1 do
 
ox = x/w
if ip_mode == "cosine" then ox = 1 - (math.cos(ox * math.pi) + 1)/2; end
xr = 1 - ox
 
r = (p0[3]*xr + p1[3]*ox)*yr + (p2[3]*xr + p3[3]*ox)*oy;
g = (p0[4]*xr + p1[4]*ox)*yr + (p2[4]*xr + p3[4]*ox)*oy;
b = (p0[5]*xr + p1[5]*ox)*yr + (p2[5]*xr + p3[5]*ox)*oy;
 
fput(x+ax,y+ay,r,g,b)
 
end;end
 
end
-- eof backdrop
 
 
 
--
-- SPLINES --
--
function db.splinePoint(x0,y0,x1,y1,x2,y2,points,point)
local x,y,sx1,sy1,sx2,sy2,f
 
f = point * 1 / points
 
sx1 = x0*(1-f) + x1*f
sy1 = y0*(1-f) + y1*f
 
sx2 = x1*(1-f) + x2*f
sy2 = y1*(1-f) + y2*f
 
x = sx1 * (1-f) + sx2 * f
y = sy1 * (1-f) + sy2 * f
 
return x,y
end
--
 
 
-- zx = 2*x1 - (x0+x2)/2
--
function db.drawSplineSegment(x0,y0,x1,y1,x2,y2,x3,y3,points,col) -- Does spline segment p1-p2
local n,x,y,sx1,sy1,sx2,sy2,mid,zx1,zy1,zx2,zy2,fx,fy
mid = math.floor(points / 2)
-- Extended Bezier points
zx1 = 2*x1 - (x0+x2)/2
zy1 = 2*y1 - (y0+y2)/2
zx2 = 2*x2 - (x1+x3)/2
zy2 = 2*y2 - (y1+y3)/2
 
fx,fy = x1,y1 -- Segment to be drawn (0),1 - 2,(3)
for n = 0, mid, 1 do
 
f = n * 1 / points * 2
 
sx1,sy1 = db.splinePoint(x0,y0,zx1,zy1,x2,y2,mid*2, mid + n)
sx2,sy2 = db.splinePoint(x1,y1,zx2,zy2,x3,y3,mid*2, n)
 
x = sx1 * (1-f) + sx2 * f
y = sy1 * (1-f) + sy2 * f
 
--putpicturepixel(x,y,col)
db.line(fx,fy,x,y,col)
fx,fy = x,y
 
end
 
end
--
 
-- eof Splines
/data/common/media/grafx2/scripts/samples_2.4/libs/memory.lua
0,0 → 1,138
-- Persistence library:
-- Memorize data for current function
-- memory.save(tab) and tab=memory.load()
--
-- The data will be stored in file called
-- <calling_function_name>.dat
-- in the lua directory
--
-- Example 1:
--
-- -- Load initial values or set defaults
-- arg = memory.load({picX=320,picY=200,scale=0})
-- -- Run an inputbox
-- OK,arg.picX,arg.picY,arg.scale = inputbox("Image Size")",
-- "Width", arg.picX, 1,2048,0,
-- "Height", arg.picY, 1,2048,0,
-- "Scale", arg.scale, 0,1,0);
-- if OK == true then
-- -- Save the selected values
-- memory.save(arg)
-- end
 
-- Example 2:
--
-- -- Load initial values or set defaults
-- arg = memory.load({x=320,y=200,scale=0})
-- picX=arg.x
-- picY=arg.y
-- scale=arg.scale
-- -- Run an inputbox
-- OK,picX,picY,scale = inputbox("Image Size")",
-- "Width", picX, 1,2048,0,
-- "Height", picY, 1,2048,0,
-- "Scale", scale, 0,1,0);
-- if OK == true then
-- -- Save the selected values
-- memory.save({x=picX,y=picY,scale=scale})
-- end
 
memory =
{
serialize = function(o)
if type(o) == "number" then
return tostring(o)
elseif type(o) == "string" then
return string.format("%q", o)
--elseif type(o) == "table" then
-- io.write("{\n")
-- for k,v in pairs(o) do
-- io.write(" ", k, " = ")
-- memory.serialize(v)
-- io.write(",\n")
-- end
-- io.write("}\n")
else
error("cannot serialize a " .. type(o))
end
end;
-- Return a string identifying the calling function.
-- Pass 1 for parent, 2 for grandparent etc.
callername = function(level)
local w
local last_slash
local info = debug.getinfo(level+1,"Sn")
local caller=tostring(info.name)
-- Function name if possible
if (caller~="nil") then
return caller
end
-- Otherwise, get file name, without extension
-- Get part after directory name
last_slash=0
while true do
local pos = string.find(info.source, "/", last_slash+1)
if (pos==nil) then break end
last_slash=pos
end
while true do
local pos = string.find(info.source, "\\", last_slash+1)
if (pos==nil) then break end
last_slash=pos
end
caller=string.sub(info.source, last_slash+1)
-- Remove file extension
if (string.sub(caller,-4, -1)==".lua") then
caller=string.sub(caller, 1, -5)
end
return caller
end;
-- Memorize some parameters.
save = function(o)
local caller=memory.callername(2)
--for k, v in pairs(o) do
-- messagebox(tostring(k))
-- messagebox(tostring(v))
--end
local f, e = io.open(caller..".dat", "w");
if (f ~= nil) then
f:write("Entry {\n")
for k, v in pairs(o) do
if (type(v)=="number") then
f:write(" "..k.."="..memory["serialize"](v)..",\n")
end
end
f:write("}\n")
f:close()
end
end;
-- Recover some saved parameters.
load = function(o)
local caller=memory.callername(2)
local i
 
function Entry (b)
-- Adds (or replaces) values in arg with those from b
for k, v in pairs(b) do
o[k]=v
end
end
local f = (loadfile(caller..".dat"))
if (f ~= nil) then
f()
end
 
return o
end;
 
}
 
return memory
/data/common/media/grafx2/scripts/samples_2.4/palette/Desaturate.lua
0,0 → 1,40
--PALETTE Adjust: Desaturate v1.1
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
-- http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
 
-- Note: Negative values will work as INCREASED saturation, but I'm not sure if this function is 100% correct
 
 
--percent = 25
 
OK,percent = inputbox("Desaturate Palette","Percent %", 25, 0,100,0);
 
--
function desaturate(percent,r,g,b) -- V1.0 by Richard Fhager
p = percent / 100
a = (math.min(math.max(r,g,b),255) + math.max(math.min(r,g,b),0)) * 0.5 * p
r = r + (a-r*p)
g = g + (a-g*p)
b = b + (a-b*p)
return r,g,b
end
--
 
if OK == true then
 
for c = 0, 255, 1 do
setcolor(c, desaturate(percent,getcolor(c)))
end
 
end
/data/common/media/grafx2/scripts/samples_2.4/palette/ExpandColors.lua
0,0 → 1,171
--PALETTE: Expand Colors v1.0
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
-- Email: dawnbringer@hem.utfors.se
-- MSN: annassar@hotmail.com
--
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
 
-- Continously fill the greatest void in the area of the color-cube enclosed by (or along ramps of) initial colors
-- This algorithm will create lines of allowed colors (all ranges) in 3d colorspace and the pick
-- new colors from the most void areas (on any line). Almost like a Median-cut in reverse.
--
-- Rather than filling the colorcube symmetrically it adds intermediate colors to the existing ones.
--
-- Running this script on the C64 16-color palette might be educational
--
--
-- Source cols#, Expand to #,
-- Ex: 15-31 means that palette colors 0-15 is expanded to 16 new colors placed at slots 16-31
--
-- Spread mode: OFF - New colors will conform to the contrast & saturation of original colors
-- (new colors will stay on the ramps possible from the original colors)
--
-- ON - New colors will expand their variance by each new addition (mostly notable when adding many new colors)
-- Will add range lines/ramps to all new colors from old ones, but keep within max/min values of the
-- original colors. 15-bit mode will dampen the spread towards extreme colors (if starting with low contrast)
--
-- 15-bit colors: Higher color-resolution, 32768 possible colors rather than the 4096 of 12bit. Slower but perhaps better.
--
 
SHADES = 16 -- Going 24bit will probably be too slow and steal too much memory, so start with 12bit (4096 colors) for now
 
ini = 0
exp = 255
 
OK,ini,exp,linemode,fbit = inputbox("Expand Colors (0-255):",
"Source Cols #: 1-254", 15, 1,254,0,
"Expand to #: 2-255", 31, 2,255,0,
"Spread mode", 0, 0,1,0,
"15-bit colors (slow)", 0, 0,1,0
);
 
if (fbit == 1) then SHADES = 32; end
 
 
 
function initColorCube(sha)
ary = {}
for z = 0, sha-1, 1 do
ary[z+1] = {}
for y = 0, sha-1, 1 do
ary[z+1][y+1] = {}
for x = 0, sha-1, 1 do
ary[z+1][y+1][x+1] = {false,0}
end
end
end
return ary
end
 
-- Gravity model (think of colors as stars of equal mass/brightness in a 3d space)
function addColor2Cube(cube,sha,r,g,b)
star = 1000000
fade = 1000
 
cube[r+1][g+1][b+1] = {false,star}
 
for z = 0, sha-1, 1 do
for y = 0, sha-1, 1 do
for x = 0, sha-1, 1 do
 
d = fade / ( (x-b)^2 + (y-g)^2 + (z-r)^2 )
 
cube[z+1][y+1][x+1][2] = cube[z+1][y+1][x+1][2] + d
 
end;end;end
end
 
 
-- Create new allowed colorlines in colorspace (ramps from which colors can be picked)
function enableRangeColorsInCube(cube,sha,r1,g1,b1,r2,g2,b2)
 
local div,r,g,b
div = 256 / sha
rs = (r2 - r1) / sha / div
gs = (g2 - g1) / sha / div
bs = (b2 - b1) / sha / div
 
for n = 0, sha-1, 1 do
 
r = math.floor(r1/div + rs * n)
g = math.floor(g1/div + gs * n)
b = math.floor(b1/div + bs * n)
 
cube[r+1][g+1][b+1][1] = true
 
end
end
 
 
function findVoid(cube,sha)
weakest = 999999999999
weak_i = {-1,-1,-1}
for z = 0, sha-1, 1 do
for y = 0, sha-1, 1 do
for x = 0, sha-1, 1 do
c = cube[z+1][y+1][x+1]
if c[1] == true then
w = c[2]
if w <= weakest then weakest = w; weak_i = {z,y,x}; end
end
end;end;end
return weak_i[1],weak_i[2],weak_i[3]
end
 
--
 
if OK == true then
 
cube = initColorCube(SHADES)
 
-- Define allowed colorspace
for y = 0, ini-1, 1 do
r1,g1,b1 = getcolor(y)
for x = y+1, ini, 1 do
r2,g2,b2 = getcolor(x)
enableRangeColorsInCube(cube,SHADES,r1,g1,b1,r2,g2,b2)
end
end
 
div = 256 / SHADES
 
-- Fill cube with initial colors
for n = 0, ini, 1 do
r,g,b = getcolor(n)
addColor2Cube(cube,SHADES,math.floor(r/div),math.floor(g/div),math.floor(b/div))
end
 
 
for n = ini+1, exp, 1 do
r,g,b = findVoid(cube,SHADES)
 
if (r == -1) then messagebox("Report:","No more colors can be found, exit at "..n); break; end
 
mult = 255 / (SHADES - 1)
setcolor(n, r*mult,g*mult,b*mult)
 
if linemode == 1 then
-- Add lines from new color to all old
for x = 0, n-1, 1 do
r2,g2,b2 = getcolor(x)
enableRangeColorsInCube(cube,SHADES,r*mult,g*mult,b*mult,r2,g2,b2) -- uses 24bit values rgb
end
end
addColor2Cube(cube,SHADES,r,g,b) -- rgb is in 'shade' format here
end
 
end
 
 
 
/data/common/media/grafx2/scripts/samples_2.4/palette/FillColorCube.lua
0,0 → 1,105
--PALETTE: Fill ColorCube voids v1.0
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
-- Email: dawnbringer@hem.utfors.se
-- MSN: annassar@hotmail.com
--
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
--
-- Create a palette by continously filling the greatest void in the RGB color-cube
--
 
 
SHADES = 16 -- Going 24bit will probably be too slow and steal too much memory, so we're 12bit (4096 colors) for now
 
ini = 0
exp = 255
 
OK,ini,exp = inputbox("Fill Palette Color voids",
"From/Keep #: 0-254", 0, 0,254,0,
"Replace to #: 1-255", 31, 1,255,0
);
 
 
function initColorCube(sha)
ary = {}
for z = 0, sha-1, 1 do
ary[z+1] = {}
for y = 0, sha-1, 1 do
ary[z+1][y+1] = {}
end
end
return ary
end
 
 
function addColor2Cube(cube,sha,r,g,b) -- Gravity model
star = 1000000
fade = 1000
 
cube[r+1][g+1][b+1] = star
for z = 0, sha-1, 1 do
for y = 0, sha-1, 1 do
for x = 0, sha-1, 1 do
 
d = fade / ( (x-b)^2 + (y-g)^2 + (z-r)^2 )
 
if cube[z+1][y+1][x+1] ~= nil then
cube[z+1][y+1][x+1] = cube[z+1][y+1][x+1] + d
else
cube[z+1][y+1][x+1] = d
end
 
end;end;end
end
 
 
function findVoid(cube,sha)
weakest = 999999999999
weak_i = {-1,-1,-1}
for z = 0, sha-1, 1 do
for y = 0, sha-1, 1 do
for x = 0, sha-1, 1 do
w = cube[z+1][y+1][x+1]
if w <= weakest then weakest = w; weak_i = {z,y,x}; end
end;end;end
return weak_i[1],weak_i[2],weak_i[3]
end
 
--
 
if OK == true then
 
cube = initColorCube(SHADES)
-- Fill cube with initial colors
for n = 0, ini-1, 1 do
r,g,b = getcolor(n)
div = SHADES
addColor2Cube(cube,SHADES,math.floor(r/div),math.floor(g/div),math.floor(b/div))
end
 
if ini == 0 then -- With no inital color, some inital data must be added to the colorcube.
addColor2Cube(cube,SHADES,0,0,0)
setcolor(0, 0,0,0)
ini = ini + 1
end
 
for n = ini, exp, 1 do
r,g,b = findVoid(cube,SHADES)
mult = 255 / (SHADES - 1)
setcolor(n, r*mult,g*mult,b*mult)
addColor2Cube(cube,SHADES,r,g,b)
end
 
end
 
 
 
/data/common/media/grafx2/scripts/samples_2.4/palette/InvertedRGB.lua
0,0 → 1,27
--PALETTE Modify: Inverted RGB
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
-- http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
 
 
for c = 0, 255, 1 do
 
r,g,b = getcolor(c)
r2 = (g+b)/2
g2 = (r+b)/2
b2 = (r+g)/2
 
setcolor(c, r2,g2,b2)
 
end
/data/common/media/grafx2/scripts/samples_2.4/palette/Set3bit.lua
0,0 → 1,39
--PALETTE Set: 3 Bit (8 Primaries)
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
 
-- Generate palette of all colors possible with a given number of shades for each channel
-- 2 shades = 1 bit / channel = 3 bit palette = 2^3 colors = 8 colors
-- 4 shades = 2 bit / channel = 6 bit palette = 2^6 colors = 64 colors
 
-- Channel shades (shades = 2 ^ bit-depth)
shades = 2
 
mult = 255 / (shades-1)
 
 
colors = {}
col = 0
for r = 0, shades-1, 1 do
for g = 0, shades-1, 1 do
for b = 0, shades-1, 1 do
col = col + 1
colors[col] = { r*mult, g*mult, b*mult }
end
end
end
 
 
for c = 1, #colors, 1 do
 
setcolor(c-1,colors[c][1],colors[c][2],colors[c][3])
 
end
/data/common/media/grafx2/scripts/samples_2.4/palette/Set6bit.lua
0,0 → 1,39
--PALETTE Set: Full 6 Bit (64 colors)
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
 
-- Generate palette of all colors possible with a given number of shades for each channel
-- 2 shades = 1 bit / channel = 3 bit palette = 2^3 colors = 8 colors
-- 4 shades = 2 bit / channel = 6 bit palette = 2^6 colors = 64 colors
 
-- Channel shades (shades = 2 ^ bit-depth)
shades = 4
 
mult = 255 / (shades-1)
 
 
colors = {}
col = 0
for r = 0, shades-1, 1 do
for g = 0, shades-1, 1 do
for b = 0, shades-1, 1 do
col = col + 1
colors[col] = { r*mult, g*mult, b*mult }
end
end
end
 
 
for c = 1, #colors, 1 do
 
setcolor(c-1,colors[c][1],colors[c][2],colors[c][3])
 
end
/data/common/media/grafx2/scripts/samples_2.4/palette/SetC64Palette.lua
0,0 → 1,50
--PALETTE Set: C64 Palette (16 colors)
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
 
OK,clean = inputbox("C64 Palette:", "Remove old palette", 0, 0,1,0
);
 
 
 
colors = {{0, 0, 0}, -- 0 Black
{62, 49,162}, -- 1 D.Blue
{87, 66, 0}, -- 2 Brown
{140, 62, 52}, -- 3 D.Red
{84, 84, 84}, -- 4 D.Grey
{141, 72,179}, -- 5 Purple
{144, 95, 37}, -- 6 Orange
{124,112,218}, -- 7 B.Blue
{128,128,128}, -- 8 Grey
{104,169, 65}, -- 9 Green
{187,119,109}, -- 10 B.Red
{122,191,199}, -- 11 Cyan
{171,171,171}, -- 12 B.Grey
{208,220,113}, -- 13 Yellow
{172,234,136}, -- 14 B.Green
{255,255,255} -- 15 White
}
 
 
if OK == true then
 
for c = 1, #colors, 1 do
setcolor(c-1,colors[c][1],colors[c][2],colors[c][3])
end
 
 
if clean == 1 then
for c = #colors+1, 256, 1 do
setcolor(c-1,0,0,0)
end
end
 
end
/data/common/media/grafx2/scripts/samples_2.4/palette/ShiftHue.lua
0,0 → 1,55
--PALETTE Adjust: Shift Hue v0.9
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- This script was adopted from Evalion, a Javascript codecrafting/imageprocessing project
-- http://goto.glocalnet.net/richard_fhager/evalion/evalion.html
 
 
--Shift_degrees = 45
 
OK,Shift_degrees = inputbox("Shift Hue v0.9","Degrees", 45, 0,360,3);
 
 
--
function shiftHUE(r,g,b,deg) -- V1.3 R.Fhager 2007, adopted from Evalion
local c,h,mi,mx,d,s,p,i,f,q,t
c = {g,b,r}
mi = math.min(r,g,b)
mx = math.max(r,g,b); v = mx;
d = mx - mi;
s = 0; if mx ~= 0 then s = d/mx; end
p = 1; if g ~= mx then p = 2; if b ~= mx then p = 0; end; end
if s~=0 then
h=(deg/60+(6+p*2+(c[1+p]-c[1+(p+1)%3])/d))%6;
i=math.floor(h);
f=h-i;
p=v*(1-s);
q=v*(1-s*f);
t=v*(1-s*(1-f));
c={v,q,p,p,t,v}
r = c[1+i]
g = c[1+(i+4)%6]
b = c[1+(i+2)%6]
end
 
return r,g,b
end
--
 
if OK == true then
 
for c = 0, 255, 1 do
r,g,b = getcolor(c)
setcolor(c, shiftHUE(r,g,b,Shift_degrees))
end
 
end
/data/common/media/grafx2/scripts/samples_2.4/picture/CellColourReducer.lua
0,0 → 1,37
-- cell colour reducer - jan'11, from Paulo Silva, with help from people from GrafX2 google group (DawnBringer, Adrien Destugues (PulkoMandy), and Yves Rizoud)
-- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. See <http://www.gnu.org/licenses/>
w,h=getpicturesize()
ok,xcell,ycell=inputbox("Modify cell pixel size","xcell",8,1,16,4,"ycell",8,1,16,4);
if ok==true then
function grayscaleindexed(c)
r,g,b=getcolor(c);return math.floor((b*11+r*30+g*59)/100);end
celcnt={};for n=0,255,1 do celcnt[n+1]=0;end -- Arraycounter must have initial value
for y1=0,h-1,ycell do
for x1=0,w-1,xcell do
for i=0,255,1 do
celcnt[i+1]=0;end
for y2=0,ycell-1,1 do
for x2=0,xcell-1,1 do
x=x1+x2;y=y1+y2;u=getpicturepixel(x,y)
celcnt[u+1]=celcnt[u+1]+(1000*xcell*ycell)+math.random(0,950);end;end
ikattr=0;paattr=0;ikcnt=0;pacnt=0
for i=0,255,1 do
if ikcnt<celcnt[i+1] then ikcnt=celcnt[i+1];ikattr=i;end;end
celcnt[ikattr+1]=0
for i=0,255,1 do
if pacnt<celcnt[i+1] then pacnt=celcnt[i+1];paattr=i;end;end
if grayscaleindexed(ikattr)>grayscaleindexed(paattr) then tmpr=ikattr;ikattr=paattr;paattr=tmpr;end
wmid=math.floor((grayscaleindexed(paattr)+grayscaleindexed(ikattr))/2)
for y2=0,ycell-1,1 do
for x2=0,xcell-1,1 do
x=x1+x2;y=y1+y2;u=getpicturepixel(x,y)
if u==ikattr then
idou=ikattr
elseif u==paattr then
idou=paattr
else
idou=ikattr
if grayscaleindexed(u)>wmid then idou=paattr;end
end
putpicturepixel(x,y,idou)
end;end;end;end;end
/data/common/media/grafx2/scripts/samples_2.4/picture/DrawGridIsometric.lua
0,0 → 1,13
-- Draw isometric grid - Copyright 2010 Paulo Silva
-- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. See <http://www.gnu.org/licenses/>
w,h=getpicturesize();
ok,gsiz,ik=inputbox("draw isometric grid","size",16,0,128,5,"colour",1,0,255,6);
if ok==true then
for y=0,h-1,gsiz do
for x=0,w-1,1 do
putpicturepixel(x,y+(x/2)%gsiz,ik);
end;end
for y=0,h-1,gsiz do
for x=0,w-1,1 do
putpicturepixel(x+((gsiz/2)-1),y+(gsiz-1)-((x/2)%gsiz),ik);
end;end;end
/data/common/media/grafx2/scripts/samples_2.4/picture/DrawGridOrthogonal_RGB.lua
0,0 → 1,14
-- draw grid - rgb (matchcolor) - Copyright 2010 Paulo Silva
-- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. See <http://www.gnu.org/licenses/>
w,h=getpicturesize()
ok,xsiz,ysiz,r,g,b=inputbox("draw grid - rgb (matchcolor)","x size",8,1,64,5,"y size",8,1,64,6,"r",128,0,255,6,"g",128,0,255,6,"b",128,0,255,6);
if ok==true then
c=matchcolor(r,g,b)
for y=0,h-1,1 do
for x=0,w-1,xsiz do
putpicturepixel(x,y,c);
end;end
for y=0,h-1,ysiz do
for x=0,w-1,1 do
putpicturepixel(x,y,c);
end;end;end
/data/common/media/grafx2/scripts/samples_2.4/picture/DrawgridOrthogonal_Index.lua
0,0 → 1,11
-- draw grid - indexed colour - Copyright 2010 Paulo Silva
-- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. See <http://www.gnu.org/licenses/>
w,h=getpicturesize();
ok,xsiz,ysiz,c=inputbox("draw grid - indexed colour)","x size",8,1,64,5,"y size",8,1,64,6,"colour id",0,0,255,6);
if ok==true then
for y=0,h-1,1 do
for x=0,w-1,xsiz do
putpicturepixel(x,y,c);end;end
for y=0,h-1,ysiz do
for x=0,w-1,1 do
putpicturepixel(x,y,c);end;end;end
/data/common/media/grafx2/scripts/samples_2.4/picture/GlassGridFilter.lua
0,0 → 1,12
-- Glass grid filter - Copyright 2010 Paulo Silva
-- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. See <http://www.gnu.org/licenses/>
w,h=getpicturesize();
ok,xsiz,ysiz=inputbox("message","xsize",8,0,64,5,"ysize",8,0,64,6);
if ok==true then
for y1=0,h-1,xsiz do
for x1=0,w-1,ysiz do
for y2=0,(ysiz/2)-1,1 do
for x2=0,xsiz-1,1 do
c1=getpicturepixel(x1+x2,y1+y2);c2=getpicturepixel(x1+(xsiz-1)-x2,y1+(ysiz-1)-y2)
putpicturepixel(x1+x2,y1+y2,c2);putpicturepixel(x1+(xsiz-1)-x2,y1+(ysiz-1)-y2,c1)
end;end;end;end;end
/data/common/media/grafx2/scripts/samples_2.4/picture/PaletteToPicture.lua
0,0 → 1,11
-- palette to picture - Copyright 2010 Paulo Silva
-- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. See <http://www.gnu.org/licenses/>
w,h=getpicturesize();
ok,xsiz,ysiz=inputbox("palette to picture","x size",8,1,16,5,"y size",8,1,16,6);
if ok==true then
for y1=0,7,1 do
for x1=0,31,1 do
for y2=0,ysiz-1,1 do
for x2=0,xsiz-1,1 do
putpicturepixel(x1*xsiz+x2,y1*ysiz+y2,y1+x1*8)
end;end;end;end;end
/data/common/media/grafx2/scripts/samples_2.4/picture/Pic2isometric.lua
0,0 → 1,87
--PICTURE (part of): 2 Isometric v0.1b
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
-- Email: dawnbringer@hem.utfors.se
-- MSN: annassar@hotmail.com
--
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
 
-- Color 0 is assumed to be the background
--
 
iso = {{0, 0, 1, 1, 1, 1, 0, 0},
{1, 1, 1, 1, 1, 1, 1, 1},
{2, 2, 1, 1, 1, 1, 3, 3},
{2, 2, 2, 2, 3, 3, 3, 3},
{2, 2, 2, 2, 3, 3, 3, 3},
{2, 2, 2, 2, 3, 3, 3, 3},
{0, 0, 2, 2, 3, 3, 0, 0}}
 
isowidth = 8
isoheight = 7
 
xoff = 0.5
yoff = 0
 
xstep = 4
ystep = 2
zstep = 4
 
-- Part of screen from top-left (4 = 1/4)
xsize = 5
ysize = 4
 
 
w, h = getpicturesize()
 
xo = math.floor(w * xoff)
 
-- just don't render more than can be fittted right now
w = math.floor(w / xsize)
h = math.floor(h / ysize)
 
 
 
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
 
isox = x * xstep - y * xstep
isoy = y * ystep + x * ystep
cb = getbackuppixel(x,y)
 
--
if cb ~= 0 then
 
r,g,b = getbackupcolor(cb);
c1 = matchcolor(r,g,b);
c2 = matchcolor(r+64, g+64, b+64);
c3 = matchcolor(r-64, g-64, b-64);
cols = {0,c1,c2,c3}
 
for iy = 1, isoheight, 1 do
for ix = 1, isowidth, 1 do
i = iso[iy][ix]
c = cols[i+1]
if i ~= 0 then putpicturepixel(xo + isox+ix-1, isoy+iy-1, c); end
end
end
 
end
--
 
end
end
 
 
 
 
/data/common/media/grafx2/scripts/samples_2.4/picture/Rainbow-Dark2Bright.lua
0,0 → 1,36
--PICTURE: Rainbow - Dark to Bright v1.1
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
-- Email: dawnbringer@hem.utfors.se
-- MSN: annassar@hotmail.com
--
 
 
--dofile("dawnbringer_lib.lua")
run("../libs/dawnbringer_lib.lua")
--> db.shiftHUE(r,g,b, deg)
 
w, h = getpicturesize()
 
for y = 0, h - 1, 1 do
for x = 0, w - 1, 1 do
 
-- Fractionalize image dimensions
ox = x / w;
oy = y / h;
 
r = 255 * math.sin(oy * 2)
g = (oy-0.5)*512 * oy
b = (oy-0.5)*512 * oy
 
r, g, b = db.shiftHUE(r,g,b,ox * 360);
c = matchcolor(r,g,b)
putpicturepixel(x, y, c);
 
end
updatescreen(); if (waitbreak(0)==1) then return; end
end
 
 
/data/common/media/grafx2/scripts/samples_2.4/picture/RemapImage2RGB.lua
0,0 → 1,50
--SCENE: Remap pic to RGB, diag.dith
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- Set Palette (to a predefined one)
 
colors = {{ 0, 0, 0},
{255, 0, 0},
{ 0,255, 0},
{ 0, 0,255}
}
 
 
chm = {1,0,0}
 
for c = 1, #colors, 1 do
setcolor(c-1,colors[c][1],colors[c][2],colors[c][3])
end
 
for c = #colors, 255, 1 do
setcolor(c,0,0,0)
end
 
 
 
w, h = getpicturesize()
 
for y = 0, h - 1, 1 do
 
for x = 0, w - 1, 1 do
r,g,b = getbackupcolor(getbackuppixel(x,y));
 
rn = r * chm[1+(y+0+x)%3]
gn = g * chm[1+(y+1+x)%3]
bn = b * chm[1+(y+2+x)%3]
 
n = matchcolor(rn,gn,bn);
 
putpicturepixel(x, y, n);
 
end
end
/data/common/media/grafx2/scripts/samples_2.4/picture/RemapImage2RGB_ed.lua
0,0 → 1,69
--SCENE: Remap pic 2 RGB, 1lineED-dith. (Same line simple error-diffusion dither)
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
 
power = 0.615
 
c1 = 0.8 -- Error weight (white is green)
c2 = 0.2 -- RGB weight (white is r+g+b)
 
-- Set Palette (to a predefined one)
 
colors = {{ 0, 0, 0},
{255, 0, 0},
{ 0,255, 0},
{ 0, 0,255}
}
 
 
chm = {1,0,0}
 
for c = 1, #colors, 1 do
setcolor(c-1,colors[c][1],colors[c][2],colors[c][3])
end
 
for c = #colors, 255, 1 do
setcolor(c,0,0,0)
end
 
 
 
w, h = getpicturesize()
 
for y = 0, h - 1, 1 do
 
re = 0
ge = 0
be = 0
 
for x = (y%2), w - 1, 1 do
r,g,b = getbackupcolor(getbackuppixel(x,y));
 
rn = re * c1 + r * chm[1+(y+0+x)%3] * c2
gn = ge * c1 + g * chm[1+(y+1+x)%3] * c2
bn = be * c1 + b * chm[1+(y+2+x)%3] * c2
 
n = matchcolor(rn,gn,bn);
 
putpicturepixel(x, y, n);
 
rn,gn,bn = getcolor(getpicturepixel(x,y));
re = (re + (r - rn)) * power
ge = (ge + (g - gn)) * power
be = (be + (b - bn)) * power
 
 
end
end
/data/common/media/grafx2/scripts/samples_2.4/picture/RemapImageTo3bitPal.lua
0,0 → 1,80
--SCENE: Remap pic to 3bit, LineEDdith. (Same line simple error-diffusion dither)
--by Richard Fhager
--http://hem.fyristorg.com/dawnbringer/
 
-- Copyright 2010 Richard Fhager
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
--
-- Just a demonstration.
--
 
 
 
power = 0.6
 
-- Channel shades (shades = 2 ^ bit-depth)
shades = 2
 
mult = 255 / (shades-1)
 
 
colors = {}
col = 0
for r = 0, shades-1, 1 do
for g = 0, shades-1, 1 do
for b = 0, shades-1, 1 do
col = col + 1
colors[col] = { r*mult, g*mult, b*mult }
end
end
end
 
 
for c = 1, #colors, 1 do
 
setcolor(c-1,colors[c][1],colors[c][2],colors[c][3])
 
end
 
 
for c = #colors, 255, 1 do
setcolor(c,0,0,0)
end
 
 
 
w, h = getpicturesize()
 
for y = 0, h - 1, 1 do
 
re = 0
ge = 0
be = 0
 
for x = (y%2), w - 1, 1 do
r,g,b = getbackupcolor(getbackuppixel(x,y));
 
rn = re + r
gn = ge + g
bn = be + b
 
n = matchcolor(rn,gn,bn);
 
putpicturepixel(x, y, n);
 
rn,gn,bn = getcolor(getpicturepixel(x,y));
re = (re + (r - rn)) * power
ge = (ge + (g - gn)) * power
be = (be + (b - bn)) * power
 
end
end
/data/common/media/grafx2/scripts/samples_2.4/picture/Tiler.lua
0,0 → 1,112
--Picture Tiler by Adrien Destugues
--Extract unique tiles from the spare page
--to the main one. Main page is erased.
--
-- Copyright 2011 Adrien Destugues <pulkomandy@pulkomandy.ath.cx>
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; version 2
-- of the License. See <http://www.gnu.org/licenses/>
 
-- Copy palette from spare to main
-- TODO
 
-- Grid size
-- TODO : get it from GrafX2
xgrid = 16;
ygrid = 16;
 
-- picture size
w, h = getpicturesize();
 
-- We may need less if there are duplicates
setsparepicturesize(xgrid, w*h/xgrid);
 
tileid = 0;
 
-- blit part of the spare to picture
function blitpicturetospare(srcx, srcy, dstx, dsty, width, height)
local x,y;
for y = 0, height - 1, 1 do
for x = 0, width - 1, 1 do
putsparepicturepixel(dstx+x, dsty+y, getpicturepixel(srcx + x, srcy + y));
end
end
end
 
function comparesparewithpicture(srcx, srcy, dstx, dsty, width, height)
local x,y,color
for y = 0, height - 1, 1 do
for x = 0, width - 1, 1 do
color = getsparepicturepixel(srcx + x, srcy + y);
if color ~= getpicturepixel(dstx+x, dsty+y) then
-- they are different
return false;
end
end
end
-- they are identical
return true;
end
 
-- compute checksum of a picture area
-- it may not be unique, we use it as a key for an hashmap
function checksum(srcx, srcy, width, height)
local sum,x,y
sum = 0;
for y = 0, height - 1, 1 do
for x = 0, width - 1, 1 do
sum = sum + getpicturepixel(srcx+x, srcy+y);
end
end
 
return sum;
end
 
tilemap = {}
 
-- foreach tile
for y = 0, h-1, ygrid do
for x = 0, w - 1, xgrid do
-- existing one ?
csum = checksum(x,y,xgrid,ygrid);
if tilemap[csum] ~= nil then
-- potential match
-- Find matching tileid
found = false;
for id in pairs(tilemap[csum]) do
-- is it a match ?
if comparesparewithpicture(x,y,0,id*ygrid, xgrid, ygrid) then
-- found it !
tilemap[csum][id] = tilemap[csum][id] + 1;
found = true;
break;
end
end
-- Add tile anyway if needed
if not found then
desty = tileid * ygrid;
blitpicturetospare(x, y, 0, desty, xgrid, ygrid);
 
-- add it to the tilemap
tilemap[csum][tileid] = 1;
-- give it a tile id
tileid = tileid + 1;
end
else
-- Copy to spare
desty = tileid * ygrid;
blitpicturetospare(x, y, 0, desty, xgrid, ygrid);
 
-- add it to the tilemap
tilemap[csum] = {}
tilemap[csum][tileid] = 1;
-- give it a tile id
tileid = tileid + 1;
end
end
end
 
setsparepicturesize(xgrid, (tileid-1)*ygrid)
--updatescreen();
/data/common/media/grafx2/scripts/samples_2.4/picture/XBitColourXpaceFromPalette.lua
0,0 → 1,12
-- Copyright 2010 Paulo Silva
-- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. See <http://www.gnu.org/licenses/>
w,h=getpicturesize();
ok,bitd=inputbox("colourspace from palette","bitdepth:",4,1,8,5);
if ok==true then
bitd3=(2^bitd);bitd8=(2^(math.floor(bitd/2)));bitd9=(2^((math.floor((bitd-1)/2))+1))
for y1=0,(bitd8-1),1 do
for x1=0,(bitd9-1),1 do
for y2=0,(bitd3-1),1 do
for x2=0,(bitd3-1),1 do
putpicturepixel(x1*bitd3+x2,y1*bitd3+y2,matchcolor((y2*255)/(bitd3-1),((y1*8+x1)*255)/(bitd3-1),(x2*255)/(bitd3-1)))
end;end;end;end;end
/data/common/media/grafx2/skins/font_Classic.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/font_DPaint.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/font_Fairlight.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/font_Fun.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/font_Melon.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/font_Seen.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/skin_Aurora.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/skin_Clax2.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/skin_Clax3.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/skin_Clax4.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/skin_DPaint.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/skin_classic.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/skin_modern.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/data/common/media/grafx2/skins/skin_scenish.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property