1997-11-24 22:05:25 +00:00
/*
* Written 1997 Jens Ch . Restemeier < jchrr @ hrz . uni - bielefeld . de >
* This program is based on an algorithm / article by
* J <EFBFBD> rn Loviscach .
1998-03-09 01:45:26 +00:00
*
* It appeared in c ' t 10 / 95 , page 326 and is called
* " Ausgew<EFBFBD> rfelt - Moderne Kunst algorithmisch erzeugen " .
* ( ~ modern art created with algorithms )
1997-11-24 22:05:25 +00:00
*
* It generates one main formula ( the middle button ) and 8 variations of it .
* If you select a variation it becomes the new main formula . If you
* press " OK " the main formula will be applied to the image .
*
* 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 ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
1998-04-13 05:44:11 +00:00
* Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
1997-11-24 22:05:25 +00:00
*
*/
/*
* History :
* 1.0 first release
* 1.2 now handles RGB *
* 1.5 fixed a small bug
* 1.6 fixed a bug that was added by v1 .5 : - (
* 1.7 added patch from Art Haas to make it compile with HP - UX , a small clean - up
* 1.8 Dscho added transform file load / save , bug - fixes
* 1.9 rewrote renderloop .
1997-12-08 21:37:39 +00:00
* 1.9 a fixed a bug .
1998-03-09 01:45:26 +00:00
* 1.9 b fixed MAIN ( )
* 1.10 added optimizer
1997-11-24 22:05:25 +00:00
*/
# include <stdio.h>
# include <stdlib.h>
1999-05-29 01:28:24 +00:00
# include <string.h>
1997-11-24 22:05:25 +00:00
# include <math.h>
# include <time.h>
1999-12-25 21:49:51 +00:00
# include "config.h"
1997-11-24 22:05:25 +00:00
# include "gtk/gtk.h"
# include "libgimp/gimp.h"
1999-12-25 21:49:51 +00:00
# include "libgimp/stdplugins-intl.h"
1997-11-24 22:05:25 +00:00
/** qbist renderer ***********************************************************/
# define MAX_TRANSFORMS 36
# define NUM_TRANSFORMS 9
# define NUM_REGISTERS 6
# define PLUG_IN_NAME "plug_in_qbist"
1998-03-09 01:45:26 +00:00
# define PLUG_IN_VERSION "March 1998, 1.10"
1997-11-24 22:05:25 +00:00
# define PREVIEW_SIZE 64
/** types *******************************************************************/
typedef gfloat vreg [ 3 ] ;
typedef struct _info {
int transformSequence [ MAX_TRANSFORMS ] ;
int source [ MAX_TRANSFORMS ] ;
int control [ MAX_TRANSFORMS ] ;
int dest [ MAX_TRANSFORMS ] ;
} s_info ;
# define PROJECTION 0
# define SHIFT 1
# define SHIFTBACK 2
# define ROTATE 3
# define ROTATE2 4
# define MULTIPLY 5
# define SINE 6
# define CONDITIONAL 7
# define COMPLEMENT 8
/** prototypes **************************************************************/
void query ( void ) ;
void run ( char * name , int nparams , GParam * param , int * nreturn_vals , GParam * * return_vals ) ;
void dialog_cancel ( ) ;
void dialog_new_variations ( GtkWidget * widget , gpointer data ) ;
void dialog_update_previews ( GtkWidget * widget , gpointer data ) ;
void dialog_select_preview ( GtkWidget * widget , s_info * n_info ) ;
int dialog_create ( ) ;
s_info qbist_info ;
/** qbist functions *********************************************************/
void create_info ( s_info * info )
{
int k ;
for ( k = 0 ; k < MAX_TRANSFORMS ; k + + ) {
info - > transformSequence [ k ] = rand ( ) % NUM_TRANSFORMS ;
info - > source [ k ] = rand ( ) % NUM_REGISTERS ;
info - > control [ k ] = rand ( ) % NUM_REGISTERS ;
info - > dest [ k ] = rand ( ) % NUM_REGISTERS ;
}
info - > dest [ rand ( ) % MAX_TRANSFORMS ] = 0 ;
}
void modify_info ( s_info * o_info , s_info * n_info )
{
int k , n ;
memcpy ( n_info , o_info , sizeof ( s_info ) ) ;
n = rand ( ) % MAX_TRANSFORMS ;
for ( k = 0 ; k < n ; k + + ) {
switch ( rand ( ) % 4 ) {
case 0 : n_info - > transformSequence [ rand ( ) % MAX_TRANSFORMS ] = rand ( ) % NUM_TRANSFORMS ; break ;
case 1 : n_info - > source [ rand ( ) % MAX_TRANSFORMS ] = rand ( ) % NUM_REGISTERS ; break ;
case 2 : n_info - > control [ rand ( ) % MAX_TRANSFORMS ] = rand ( ) % NUM_REGISTERS ; break ;
case 3 : n_info - > dest [ rand ( ) % MAX_TRANSFORMS ] = rand ( ) % NUM_REGISTERS ; break ;
}
}
}
1998-03-09 01:45:26 +00:00
/*
* Optimizer
*/
int used_trans_flag [ MAX_TRANSFORMS ] ;
int used_reg_flag [ NUM_REGISTERS ] ;
void check_last_modified ( s_info info , int p , int n )
{
p - - ;
while ( ( p > = 0 ) & & ( info . dest [ p ] ! = n ) ) p - - ;
if ( p < 0 )
used_reg_flag [ n ] = 1 ;
else {
used_trans_flag [ p ] = 1 ;
check_last_modified ( info , p , info . source [ p ] ) ;
check_last_modified ( info , p , info . control [ p ] ) ;
}
}
void optimize ( s_info info )
{
int i ;
/* double-arg fix: */
for ( i = 0 ; i < MAX_TRANSFORMS ; i + + ) {
used_trans_flag [ i ] = 0 ;
if ( i < NUM_REGISTERS )
used_reg_flag [ i ] = 0 ;
/* double-arg fix: */
switch ( info . transformSequence [ i ] ) {
case ROTATE :
case ROTATE2 :
case COMPLEMENT :
info . control [ i ] = info . dest [ i ] ;
break ;
}
}
/* check for last modified item */
check_last_modified ( info , MAX_TRANSFORMS , 0 ) ;
}
1997-11-24 22:05:25 +00:00
void qbist ( s_info info , gchar * buffer , int xp , int yp , int num , int width , int height , int bpp )
{
gushort gx ;
vreg reg [ NUM_REGISTERS ] ;
int i ;
gushort sr , cr , dr ;
if ( num < = 0 ) return ;
for ( gx = 0 ; gx < num ; gx + + ) {
for ( i = 0 ; i < NUM_REGISTERS ; i + + ) {
1998-03-09 01:45:26 +00:00
if ( used_reg_flag [ i ] ) {
reg [ i ] [ 0 ] = ( ( float ) gx + xp ) / ( ( float ) ( width ) ) ;
reg [ i ] [ 1 ] = ( ( float ) yp ) / ( ( float ) ( height ) ) ;
reg [ i ] [ 2 ] = ( ( float ) i ) / ( ( float ) NUM_REGISTERS ) ;
}
1997-11-24 22:05:25 +00:00
}
for ( i = 0 ; i < MAX_TRANSFORMS ; i + + ) {
sr = info . source [ i ] ; cr = info . control [ i ] ; dr = info . dest [ i ] ;
1998-03-09 01:45:26 +00:00
if ( used_trans_flag [ i ] ) switch ( info . transformSequence [ i ] ) {
1997-11-24 22:05:25 +00:00
case PROJECTION : {
gfloat scalarProd ;
scalarProd = ( reg [ sr ] [ 0 ] * reg [ cr ] [ 0 ] ) + ( reg [ sr ] [ 1 ] * reg [ cr ] [ 1 ] ) + ( reg [ sr ] [ 2 ] * reg [ cr ] [ 2 ] ) ;
reg [ dr ] [ 0 ] = scalarProd * reg [ sr ] [ 0 ] ;
reg [ dr ] [ 1 ] = scalarProd * reg [ sr ] [ 1 ] ;
reg [ dr ] [ 2 ] = scalarProd * reg [ sr ] [ 2 ] ;
break ;
}
case SHIFT :
reg [ dr ] [ 0 ] = reg [ sr ] [ 0 ] + reg [ cr ] [ 0 ] ;
if ( reg [ dr ] [ 0 ] > = 1.0 ) reg [ dr ] [ 0 ] - = 1.0 ;
reg [ dr ] [ 1 ] = reg [ sr ] [ 1 ] + reg [ cr ] [ 1 ] ;
if ( reg [ dr ] [ 1 ] > = 1.0 ) reg [ dr ] [ 1 ] - = 1.0 ;
reg [ dr ] [ 2 ] = reg [ sr ] [ 2 ] + reg [ cr ] [ 2 ] ;
if ( reg [ dr ] [ 2 ] > = 1.0 ) reg [ dr ] [ 2 ] - = 1.0 ;
break ;
case SHIFTBACK :
reg [ dr ] [ 0 ] = reg [ sr ] [ 0 ] - reg [ cr ] [ 0 ] ;
if ( reg [ dr ] [ 0 ] < = 0.0 ) reg [ dr ] [ 0 ] + = 1.0 ;
reg [ dr ] [ 1 ] = reg [ sr ] [ 1 ] - reg [ cr ] [ 1 ] ;
if ( reg [ dr ] [ 1 ] < = 0.0 ) reg [ dr ] [ 1 ] + = 1.0 ;
reg [ dr ] [ 2 ] = reg [ sr ] [ 2 ] - reg [ cr ] [ 2 ] ;
if ( reg [ dr ] [ 2 ] < = 0.0 ) reg [ dr ] [ 2 ] + = 1.0 ;
break ;
case ROTATE :
reg [ dr ] [ 0 ] = reg [ sr ] [ 1 ] ;
reg [ dr ] [ 1 ] = reg [ sr ] [ 2 ] ;
reg [ dr ] [ 2 ] = reg [ sr ] [ 0 ] ;
break ;
case ROTATE2 :
reg [ dr ] [ 0 ] = reg [ sr ] [ 2 ] ;
reg [ dr ] [ 1 ] = reg [ sr ] [ 0 ] ;
reg [ dr ] [ 2 ] = reg [ sr ] [ 1 ] ;
break ;
case MULTIPLY :
reg [ dr ] [ 0 ] = reg [ sr ] [ 0 ] * reg [ cr ] [ 0 ] ;
reg [ dr ] [ 1 ] = reg [ sr ] [ 1 ] * reg [ cr ] [ 1 ] ;
reg [ dr ] [ 2 ] = reg [ sr ] [ 2 ] * reg [ cr ] [ 2 ] ;
break ;
case SINE :
reg [ dr ] [ 0 ] = 0.5 + ( 0.5 * sin ( 20.0 * reg [ sr ] [ 0 ] * reg [ cr ] [ 0 ] ) ) ;
reg [ dr ] [ 1 ] = 0.5 + ( 0.5 * sin ( 20.0 * reg [ sr ] [ 1 ] * reg [ cr ] [ 1 ] ) ) ;
reg [ dr ] [ 2 ] = 0.5 + ( 0.5 * sin ( 20.0 * reg [ sr ] [ 2 ] * reg [ cr ] [ 2 ] ) ) ;
break ;
case CONDITIONAL :
if ( ( reg [ cr ] [ 0 ] + reg [ cr ] [ 1 ] + reg [ cr ] [ 2 ] ) > 0.5 ) {
reg [ dr ] [ 0 ] = reg [ sr ] [ 0 ] ;
reg [ dr ] [ 1 ] = reg [ sr ] [ 1 ] ;
reg [ dr ] [ 2 ] = reg [ sr ] [ 2 ] ;
} else {
reg [ dr ] [ 0 ] = reg [ cr ] [ 0 ] ;
reg [ dr ] [ 1 ] = reg [ cr ] [ 1 ] ;
reg [ dr ] [ 2 ] = reg [ cr ] [ 2 ] ;
}
break ;
case COMPLEMENT :
reg [ dr ] [ 0 ] = 1.0 - reg [ sr ] [ 0 ] ;
reg [ dr ] [ 1 ] = 1.0 - reg [ sr ] [ 1 ] ;
reg [ dr ] [ 2 ] = 1.0 - reg [ sr ] [ 2 ] ;
break ;
}
}
for ( i = 0 ; i < bpp ; i + + ) {
if ( i < 3 ) {
int a ;
a = 255.0 * reg [ 0 ] [ i ] ;
buffer [ i ] = ( a < 0 ) ? 0 : ( ( a > 255 ) ? 255 : a ) ;
} else {
buffer [ i ] = 255 ;
}
}
buffer + = bpp ;
}
}
/** Plugin interface *********************************************************/
GPlugInInfo PLUG_IN_INFO = {
NULL , /* init_proc */
NULL , /* quit_proc */
query , /* query_proc */
run /* run_proc */
} ;
/* Definition of parameters */
GParamDef args [ ] = {
{ PARAM_INT32 , " run_mode " , " Interactive, non-interactive " } ,
{ PARAM_IMAGE , " image " , " Input image (unused) " } ,
{ PARAM_DRAWABLE , " drawable " , " Input drawable " }
} ;
GParamDef * return_vals = NULL ;
int nargs = sizeof ( args ) / sizeof ( args [ 0 ] ) ;
int nreturn_vals = 0 ;
1998-03-09 01:45:26 +00:00
MAIN ( )
1997-11-24 22:05:25 +00:00
void query ( void )
{
1999-12-25 21:49:51 +00:00
INIT_I18N ( ) ;
1997-11-24 22:05:25 +00:00
gimp_install_procedure ( PLUG_IN_NAME ,
1999-12-25 21:49:51 +00:00
_ ( " Create images based on a random genetic formula " ) ,
_ ( " This Plug-in is based on an article by J<> rn Loviscach (appeared in c't 10/95, page 326). It generates modern art pictures from a random genetic formula. " ) ,
1997-11-24 22:05:25 +00:00
" J<EFBFBD> rn Loviscach, Jens Ch. Restemeier " ,
" J<EFBFBD> rn Loviscach, Jens Ch. Restemeier " ,
PLUG_IN_VERSION ,
1999-12-25 21:49:51 +00:00
N_ ( " <Image>/Filters/Render/Pattern/Qbist... " ) ,
1997-11-24 22:05:25 +00:00
" RGB* " ,
PROC_PLUG_IN ,
nargs ,
nreturn_vals ,
args ,
return_vals ) ;
}
/* Return values */
GParam values [ 1 ] ;
void run ( char * name , int nparams , GParam * param , int * nreturn_vals , GParam * * return_vals )
{
gint sel_x1 , sel_y1 , sel_x2 , sel_y2 ;
gint img_height , img_width , img_bpp , img_has_alpha ;
GDrawable * drawable ;
GRunModeType run_mode ;
GStatusType status ;
* nreturn_vals = 1 ;
* return_vals = values ;
status = STATUS_SUCCESS ;
if ( param [ 0 ] . type ! = PARAM_INT32 )
status = STATUS_CALLING_ERROR ;
run_mode = param [ 0 ] . data . d_int32 ;
1999-12-25 21:49:51 +00:00
if ( run_mode = = RUN_INTERACTIVE ) {
INIT_I18N_UI ( ) ;
} else {
INIT_I18N ( ) ;
}
1997-11-24 22:05:25 +00:00
if ( param [ 2 ] . type ! = PARAM_DRAWABLE )
status = STATUS_CALLING_ERROR ;
drawable = gimp_drawable_get ( param [ 2 ] . data . d_drawable ) ;
img_width = gimp_drawable_width ( drawable - > id ) ;
img_height = gimp_drawable_height ( drawable - > id ) ;
img_bpp = gimp_drawable_bpp ( drawable - > id ) ;
img_has_alpha = gimp_drawable_has_alpha ( drawable - > id ) ;
gimp_drawable_mask_bounds ( drawable - > id , & sel_x1 , & sel_y1 , & sel_x2 , & sel_y2 ) ;
1999-10-24 20:49:09 +00:00
if ( ! gimp_drawable_is_rgb ( drawable - > id ) )
1997-11-24 22:05:25 +00:00
status = STATUS_CALLING_ERROR ;
if ( status = = STATUS_SUCCESS ) {
create_info ( & qbist_info ) ;
switch ( run_mode ) {
case RUN_INTERACTIVE :
/* Possibly retrieve data */
gimp_get_data ( PLUG_IN_NAME , & qbist_info ) ;
/* Get information from the dialog */
if ( dialog_create ( ) ) {
status = STATUS_SUCCESS ;
gimp_set_data ( PLUG_IN_NAME , & qbist_info , sizeof ( s_info ) ) ;
} else
status = STATUS_EXECUTION_ERROR ;
break ;
case RUN_NONINTERACTIVE :
status = STATUS_CALLING_ERROR ;
break ;
case RUN_WITH_LAST_VALS :
/* Possibly retrieve data */
gimp_get_data ( PLUG_IN_NAME , & qbist_info ) ;
status = STATUS_SUCCESS ;
break ;
default :
status = STATUS_CALLING_ERROR ;
break ;
}
if ( status = = STATUS_SUCCESS ) {
GPixelRgn imagePR ;
guchar * row_data ;
gint row ;
gimp_tile_cache_ntiles ( ( drawable - > width + gimp_tile_width ( ) - 1 ) / gimp_tile_width ( ) ) ;
gimp_pixel_rgn_init ( & imagePR , drawable , 0 , 0 , img_width , img_height , TRUE , TRUE ) ;
row_data = ( guchar * ) malloc ( ( sel_x2 - sel_x1 ) * img_bpp ) ;
1998-03-09 01:45:26 +00:00
optimize ( qbist_info ) ;
1999-12-25 21:49:51 +00:00
gimp_progress_init ( _ ( " Qbist ... " ) ) ;
1997-11-24 22:05:25 +00:00
for ( row = sel_y1 ; row < sel_y2 ; row + + ) {
gimp-joke-980321
* app/iscissors.c, app/tips_dialog.c, app/gradient.c,
libgimp/gimp.c, plug-ins/AlienMap/AlienMap.c,
plug-ins/bmp/bmp.c, plug-ins/fits/fitsrw.h,
plug-ins/fits/fitsrw.c, plug-ins/flarefx/flarefx.c,
plug-ins/gfig/gfig.c, plug-ins/gfli/gfli.c,
plug-ins/gicon/gicon.c, plug-ins/gqbist/gqbist.c,
plug-ins/gtm/gtm.c, plug-ins/hot/hot.c,
plug-ins/ifscompose/ifscompose.c,
plug-ins/ifscompose/ifscompose_utils.c
plug-ins/max_rgb/max_rgb.c, plug-ins/nlfilt/nlfilt.c,
plug-ins/pat/pat.c, plug-ins/pcx/pcx.c, plug-ins/rotate/rotate.c,
plug-ins/script-fu/script-fu-server.c, plug-ins/snoise/snoise.c,
plug-ins/threshold_alpha/threshold_alpha.c,
plug-ins/zealouscrop/zealouscrop.c :gimp-joke-980321
plug-ins/CML_explorer, plug-ins/autocrop,
plug-ins/align_layers, plug-ins/blinds,
plug-ins/bmp, plug-ins/megawidget: gimp-joke-980322
Applied gimp-joke-980322-0.patch and gimp-joke-980321-0.patch
from Yasuhiro SHIRASAKI <joke@awa.tohoku.ac.jp>. Mostly
portability for DEC osf1's cc. Lots of MAIN();'s, trailing
commas in enums, and guchar/gchar madness.
Gimp now sends mail, cleans vinyl records,
removes stubborn stains, julien fries, and more!
-adrian
1998-03-22 20:44:39 +00:00
qbist ( qbist_info , ( gchar * ) row_data , 0 , row , sel_x2 - sel_x1 , sel_x2 - sel_x1 , sel_y2 - sel_y1 , img_bpp ) ;
1997-11-24 22:05:25 +00:00
gimp_pixel_rgn_set_row ( & imagePR , row_data , sel_x1 , row , ( sel_x2 - sel_x1 ) ) ;
if ( ( row % 5 ) = = 0 )
gimp_progress_update ( ( gfloat ) ( row - sel_y1 ) / ( gfloat ) ( sel_y2 - sel_y1 ) ) ;
}
free ( row_data ) ;
gimp_drawable_flush ( drawable ) ;
gimp_drawable_merge_shadow ( drawable - > id , TRUE ) ;
gimp_drawable_update ( drawable - > id , sel_x1 , sel_y1 , ( sel_x2 - sel_x1 ) , ( sel_y2 - sel_y1 ) ) ;
gimp_displays_flush ( ) ;
}
}
values [ 0 ] . type = PARAM_STATUS ;
values [ 0 ] . data . d_status = status ;
gimp_drawable_detach ( drawable ) ;
}
/** User interface ***********************************************************/
GtkWidget * preview [ 9 ] ;
s_info info [ 9 ] ;
gint result ;
void dialog_close ( GtkWidget * widget , gpointer data )
{
gtk_main_quit ( ) ;
}
void dialog_cancel ( GtkWidget * widget , gpointer data )
{
gtk_widget_destroy ( GTK_WIDGET ( data ) ) ;
}
void dialog_ok ( GtkWidget * widget , gpointer data )
{
result = TRUE ;
gtk_widget_destroy ( GTK_WIDGET ( data ) ) ;
}
void dialog_new_variations ( GtkWidget * widget , gpointer data )
{
int i ;
for ( i = 1 ; i < 9 ; i + + )
modify_info ( & ( info [ 0 ] ) , & ( info [ i ] ) ) ;
}
void dialog_update_previews ( GtkWidget * widget , gpointer data )
{
int i , j ;
guchar buf [ PREVIEW_SIZE * 3 ] ;
for ( j = 0 ; j < 9 ; j + + ) {
1998-03-09 01:45:26 +00:00
optimize ( info [ ( j + 5 ) % 9 ] ) ;
1997-11-24 22:05:25 +00:00
for ( i = 0 ; i < PREVIEW_SIZE ; i + + ) {
1998-03-19 02:11:53 +00:00
qbist ( info [ ( j + 5 ) % 9 ] , ( gchar * ) buf , 0 , i , PREVIEW_SIZE , PREVIEW_SIZE , PREVIEW_SIZE , 3 ) ;
1997-11-24 22:05:25 +00:00
gtk_preview_draw_row ( GTK_PREVIEW ( preview [ j ] ) , buf , 0 , i , PREVIEW_SIZE ) ;
}
gtk_widget_draw ( preview [ j ] , NULL ) ;
}
}
void dialog_select_preview ( GtkWidget * widget , s_info * n_info )
{
memcpy ( & ( info [ 0 ] ) , n_info , sizeof ( s_info ) ) ;
dialog_new_variations ( widget , NULL ) ;
dialog_update_previews ( widget , NULL ) ;
}
/* File I/O stuff */
# define LOBITE(x) ((x)&0xff)
# define HIBITE(x) ((x)>>8)
# define MACBITES(x) (HIBITE(x)+LOBITE(x)<<8)
# define GETMACUSHORT(f) ((fgetc(f)<<8)+(fgetc(f)))
# define PUTMACUSHORT(u, f) fprintf(f, "%c%c", HIBITE(u), LOBITE(u));
int load_data ( char * name )
{
int i ;
FILE * f ;
f = fopen ( name , " rb " ) ;
if ( f = = NULL ) return ( 0 ) ;
for ( i = 0 ; i < MAX_TRANSFORMS ; i + + ) info [ 0 ] . transformSequence [ i ] = GETMACUSHORT ( f ) ;
for ( i = 0 ; i < MAX_TRANSFORMS ; i + + ) info [ 0 ] . source [ i ] = GETMACUSHORT ( f ) ;
for ( i = 0 ; i < MAX_TRANSFORMS ; i + + ) info [ 0 ] . control [ i ] = GETMACUSHORT ( f ) ;
for ( i = 0 ; i < MAX_TRANSFORMS ; i + + ) info [ 0 ] . dest [ i ] = GETMACUSHORT ( f ) ;
fclose ( f ) ;
return ( 1 ) ;
}
1998-03-09 01:45:26 +00:00
void save_data ( char * name )
1997-11-24 22:05:25 +00:00
{
int i = 0 ;
FILE * f ;
f = fopen ( name , " wb " ) ;
1998-03-09 01:45:26 +00:00
for ( i = 0 ; i < MAX_TRANSFORMS ; i + + ) PUTMACUSHORT ( info [ 0 ] . transformSequence [ i ] , f ) ;
for ( i = 0 ; i < MAX_TRANSFORMS ; i + + ) PUTMACUSHORT ( info [ 0 ] . source [ i ] , f ) ;
for ( i = 0 ; i < MAX_TRANSFORMS ; i + + ) PUTMACUSHORT ( info [ 0 ] . control [ i ] , f ) ;
for ( i = 0 ; i < MAX_TRANSFORMS ; i + + ) PUTMACUSHORT ( info [ 0 ] . dest [ i ] , f ) ;
1997-11-24 22:05:25 +00:00
fclose ( f ) ;
}
void file_selection_save ( GtkWidget * widget , GtkWidget * file_select )
{
1998-03-09 01:45:26 +00:00
save_data ( gtk_file_selection_get_filename ( GTK_FILE_SELECTION ( file_select ) ) ) ;
1997-11-24 22:05:25 +00:00
gtk_widget_destroy ( file_select ) ;
}
void file_selection_load ( GtkWidget * widget , GtkWidget * file_select )
{
load_data ( gtk_file_selection_get_filename ( GTK_FILE_SELECTION ( file_select ) ) ) ;
gtk_widget_destroy ( file_select ) ;
dialog_new_variations ( widget , NULL ) ;
dialog_update_previews ( widget , NULL ) ;
}
void file_selection_cancel ( GtkWidget * widget , GtkWidget * file_select )
{
gtk_widget_destroy ( file_select ) ;
}
void dialog_load ( GtkWidget * widget , gpointer d )
{
GtkWidget * file_select ;
1999-12-25 21:49:51 +00:00
file_select = gtk_file_selection_new ( _ ( " Load QBE file... " ) ) ;
1997-11-24 22:05:25 +00:00
gtk_signal_connect ( GTK_OBJECT ( GTK_FILE_SELECTION ( file_select ) - > ok_button ) ,
" clicked " , ( GtkSignalFunc ) file_selection_load ,
( gpointer ) file_select ) ;
gtk_signal_connect ( GTK_OBJECT ( GTK_FILE_SELECTION ( file_select ) - > cancel_button ) ,
" clicked " , ( GtkSignalFunc ) file_selection_cancel ,
( gpointer ) file_select ) ;
gtk_widget_show ( file_select ) ;
}
void dialog_save ( GtkWidget * widget , gpointer d )
{
GtkWidget * file_select ;
1999-12-25 21:49:51 +00:00
file_select = gtk_file_selection_new ( _ ( " Save (middle transform) as QBE file... " ) ) ;
1997-11-24 22:05:25 +00:00
gtk_signal_connect ( GTK_OBJECT ( GTK_FILE_SELECTION ( file_select ) - > ok_button ) ,
" clicked " , ( GtkSignalFunc ) file_selection_save ,
( gpointer ) file_select ) ;
gtk_signal_connect ( GTK_OBJECT ( GTK_FILE_SELECTION ( file_select ) - > cancel_button ) ,
" clicked " , ( GtkSignalFunc ) file_selection_cancel ,
( gpointer ) file_select ) ;
gtk_widget_show ( file_select ) ;
}
int dialog_create ( )
{
GtkWidget * dialog ;
GtkWidget * button ;
GtkWidget * table ;
guchar * color_cube ;
gchar * * argv ;
gint argc ;
int i ;
srand ( time ( NULL ) ) ;
argc = 1 ;
argv = g_new ( gchar * , 1 ) ;
argv [ 0 ] = g_strdup ( " video " ) ;
gtk_init ( & argc , & argv ) ;
gtk_rc_parse ( gimp_gtkrc ( ) ) ;
gdk_set_use_xshm ( gimp_use_xshm ( ) ) ;
gtk_preview_set_gamma ( gimp_gamma ( ) ) ;
gtk_preview_set_install_cmap ( gimp_install_cmap ( ) ) ;
color_cube = gimp_color_cube ( ) ;
gtk_preview_set_color_cube ( color_cube [ 0 ] , color_cube [ 1 ] ,
color_cube [ 2 ] , color_cube [ 3 ] ) ;
gtk_widget_set_default_visual ( gtk_preview_get_visual ( ) ) ;
gtk_widget_set_default_colormap ( gtk_preview_get_cmap ( ) ) ;
dialog = gtk_dialog_new ( ) ;
1999-12-28 20:04:19 +00:00
gtk_window_set_title ( GTK_WINDOW ( dialog ) , " G-Qbist 1.10 " ) ;
1997-11-24 22:05:25 +00:00
gtk_signal_connect ( GTK_OBJECT ( dialog ) , " destroy " ,
( GtkSignalFunc ) dialog_close ,
NULL ) ;
table = gtk_table_new ( 3 , 3 , FALSE ) ;
gtk_table_set_row_spacings ( GTK_TABLE ( table ) , 5 ) ;
gtk_table_set_col_spacings ( GTK_TABLE ( table ) , 5 ) ;
gtk_container_border_width ( GTK_CONTAINER ( table ) , 5 ) ;
1998-03-09 01:45:26 +00:00
gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG ( dialog ) - > vbox ) , table , TRUE , TRUE , 0 ) ;
1997-11-24 22:05:25 +00:00
gtk_widget_show ( table ) ;
memcpy ( ( char * ) & ( info [ 0 ] ) , ( char * ) & qbist_info , sizeof ( s_info ) ) ;
dialog_new_variations ( NULL , NULL ) ;
for ( i = 0 ; i < 9 ; i + + ) {
button = gtk_button_new ( ) ;
gtk_signal_connect ( GTK_OBJECT ( button ) , " clicked " ,
( GtkSignalFunc ) dialog_select_preview , ( gpointer ) & ( info [ ( i + 5 ) % 9 ] ) ) ;
gtk_table_attach ( GTK_TABLE ( table ) , button , i % 3 , ( i % 3 ) + 1 , i / 3 , ( i / 3 ) + 1 ,
GTK_EXPAND | GTK_FILL , GTK_EXPAND | GTK_FILL , 0 , 0 ) ;
gtk_widget_show ( button ) ;
preview [ i ] = gtk_preview_new ( GTK_PREVIEW_COLOR ) ;
gtk_preview_size ( GTK_PREVIEW ( preview [ i ] ) , PREVIEW_SIZE , PREVIEW_SIZE ) ;
gtk_container_add ( GTK_CONTAINER ( button ) , preview [ i ] ) ;
gtk_widget_show ( preview [ i ] ) ;
}
dialog_update_previews ( NULL , NULL ) ;
1999-12-25 21:49:51 +00:00
button = gtk_button_new_with_label ( _ ( " OK " ) ) ;
1997-11-24 22:05:25 +00:00
gtk_signal_connect ( GTK_OBJECT ( button ) , " clicked " ,
( GtkSignalFunc ) dialog_ok ,
( gpointer ) dialog ) ;
GTK_WIDGET_SET_FLAGS ( button , GTK_CAN_DEFAULT ) ;
gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG ( dialog ) - > action_area ) , button , TRUE , TRUE , 0 ) ;
gtk_widget_show ( button ) ;
1999-12-25 21:49:51 +00:00
button = gtk_button_new_with_label ( _ ( " Load " ) ) ;
1997-11-24 22:05:25 +00:00
gtk_signal_connect ( GTK_OBJECT ( button ) , " clicked " ,
( GtkSignalFunc ) dialog_load ,
( gpointer ) dialog ) ;
GTK_WIDGET_SET_FLAGS ( button , GTK_CAN_DEFAULT ) ;
gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG ( dialog ) - > action_area ) , button , TRUE , TRUE , 0 ) ;
gtk_widget_show ( button ) ;
1999-12-25 21:49:51 +00:00
button = gtk_button_new_with_label ( _ ( " Save " ) ) ;
1997-11-24 22:05:25 +00:00
gtk_signal_connect ( GTK_OBJECT ( button ) , " clicked " ,
( GtkSignalFunc ) dialog_save ,
( gpointer ) dialog ) ;
GTK_WIDGET_SET_FLAGS ( button , GTK_CAN_DEFAULT ) ;
gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG ( dialog ) - > action_area ) , button , TRUE , TRUE , 0 ) ;
gtk_widget_show ( button ) ;
1999-12-25 21:49:51 +00:00
button = gtk_button_new_with_label ( _ ( " Cancel " ) ) ;
1997-11-24 22:05:25 +00:00
gtk_signal_connect ( GTK_OBJECT ( button ) , " clicked " ,
( GtkSignalFunc ) dialog_cancel ,
( gpointer ) dialog ) ;
gtk_box_pack_end ( GTK_BOX ( GTK_DIALOG ( dialog ) - > action_area ) , button , TRUE , TRUE , 0 ) ;
GTK_WIDGET_SET_FLAGS ( button , GTK_CAN_DEFAULT ) ;
gtk_widget_grab_default ( button ) ;
gtk_widget_show ( button ) ;
gtk_widget_show ( dialog ) ;
result = FALSE ;
gtk_main ( ) ;
gdk_flush ( ) ;
if ( result )
memcpy ( ( char * ) & qbist_info , ( char * ) & ( info [ 0 ] ) , sizeof ( s_info ) ) ;
return result ;
}