Oyranos Color Management System API - Version 0.9.6
image_display.cpp

Image viewer example.

#include <ctime>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include "oyranos_config_internal.h" /* I18N */
#include "oyranos_i18n.h"
#include "oyranos_sentinel.h" /* oyInit_() */
#include <oyranos.h>
#include <oyranos_cmm.h> /* for hacking into module API */
#include <oyranos_io.h> /* oyFindApplication() */
#include "oyranos_string.h"
#include <oyConversion_s.h>
#include <oyProfiles_s.h>
#ifdef DEBUG
#undef DEBUG
#endif
#define DEBUG 1
extern "C" {
#include "GLee.h"
}
#include "../../oyranos_logo.h"
#include "oyranos_display_helper_classes_fltk.cpp" // observer callback
#include "Oy_Fl_Group.h"
#include "Oy_Fl_GL_Box.h"
#include "Oy_Fl_Shader_Box.h"
#include "Oy_Fl_Image_Box.h"
#include <FL/Fl_Tile.H>
#include <FL/Fl_Menu_Button.H>
oyConversion_s * idcc = 0;
Oy_Fl_Image_Widget * oy_widget = 0;
Oy_Fl_Double_Window * win = 0;
Oy_Fl_Group * lg = 0;
extern "C" {
/* forward declaration of oyranos_alpha.c */
int oyWriteMemToFile_ ( const char*, const void*, size_t );
char* oyReadFileToMem_ (const char* fullFileName, size_t *size,
oyAlloc_f allocate_func);
}
Oy_Fl_Double_Window * createWindow (Oy_Fl_Image_Widget ** oy_box, uint32_t flags);
void setWindowMenue ( Oy_Fl_Double_Window*win,
Oy_Fl_Image_Widget* oy_box,
oyFilterNode_s * node );
void jobResultRepeatCb(void*)
{
Fl::repeat_timeout(0.02, (void(*)(void*))jobResultRepeatCb);
}
/* keep at least one node around to handle options */
static oyFilterNode_s * icc = 0;
int
main(int argc, char** argv)
{
// activate FLTK thread support
Fl::lock();
/* some Oyranos types */
int file_pos = 1;
const char * file_name = NULL;
int gl_box = 0x01;
int logo = 0x02;
const char * icc_color_context = 0;
const char * clut_name = 0;
int i;
oyOptions_s * module_options = NULL;
uint32_t icc_profile_flags = 0;
#ifdef USE_GETTEXT
setlocale(LC_ALL,"");
#endif
oyExportStart_(EXPORT_CHECK_NO);
/* workaround to initialise OpenMP in order to get code compiled under osX 10.6.8 */
#pragma omp parallel for private(i)
for(i = 0; i < 1; ++i)
file_pos = 1;
/* handle arguments */
for(i = 1; i < argc; ++i)
{
if(argc > 1 && strcmp(argv[i], "-v") == 0)
{
oy_display_verbose = 1;
++file_pos;
}
if(argc > 1 && strcmp(argv[i], "--no-logo") == 0)
{
logo = 0;
++file_pos;
}
if(argc > 1 && strcmp(argv[i], "--use-pixel") == 0)
{
gl_box = 0;
++file_pos;
}
if(argc > 2 && strcmp(argv[i], "--icc-color-context") == 0)
{
icc_color_context = argv[i+1];
icc_color_context, OY_CREATE_NEW );
icc_profile_flags = oyICCProfileSelectionFlagsFromRegistration( icc_color_context );
++file_pos;
++file_pos;
}
if(argc > 2 && strcmp(argv[i], "--effect") == 0)
{
"1", OY_CREATE_NEW );
oyProfiles_s * effects = oyProfiles_New(0);
oyProfile_s * p = oyProfile_FromName( argv[i+1], icc_profile_flags, 0 );
oyProfiles_MoveIn( effects, &p, -1 );
oyOptions_MoveInStruct( &module_options,
(oyStruct_s**) &effects,
/*oyOptions_SetFromText( &module_options, OY_DEFAULT_EFFECT_PROFILE,
argv[i+1], OY_CREATE_NEW );*/
++file_pos;
++file_pos;
}
if(argc > 2 && strcmp(argv[i], "--shader") == 0)
{
gl_box = 0x04;
clut_name = argv[i+1];
++file_pos;
++file_pos;
}
if(argc > 1 && (strcmp(argv[i], "--help") == 0 ||
strcmp(argv[i], "-h") == 0 ) )
{
printf("Usage: image_display [options] <image_file>\n"
"\t--use-pixel\tuse normal pixel copy\n"
"\t--no-logo\tskip Oyranos logo\n"
"\t--icc-color-context <name>\tselect a Oyranos wrapped context CMM\n"
"\t--effect <name>\tselect a effect profile\n"
"\t--shader <file>\tset a CLUT from PPM image for color transform\n"
"\t-v\t\tprint verbosely\n"
"\t--help\t\tprint this help text\n"
);
exit(0);
}
}
for(i = 0; i < argc; ++i)
fprintf(stderr, "argv[%d] = %s\n", i, argv[i] );
if(argc > file_pos && argv[file_pos])
file_name = argv[file_pos];
else
file_name = "../../oyranos_logo.ppm";
/* setup the drawing box */
Oy_Fl_Shader_Box * oy_shader_box = 0;
Oy_Fl_GL_Box * oy_gl_box = 0;
Oy_Fl_Image_Box * oy_box = 0;
win = createWindow( &oy_widget, gl_box | logo );
int error = 0;
if(oy_widget)
{
if(gl_box)
{
if(gl_box & 0x04)
{
oy_shader_box = dynamic_cast<Oy_Fl_Shader_Box*> (oy_widget);
error = oy_shader_box->setImage( file_name, module_options, clut_name );
if(!error)
fprintf(stderr, "setImage fine\n");
else
fprintf(stderr, "setImage failed: %s\n", clut_name);
} else
{
oy_gl_box = dynamic_cast<Oy_Fl_GL_Box*> (oy_widget);
icc = oy_gl_box->setImage( file_name, module_options );
}
} else
{
oy_box = dynamic_cast<Oy_Fl_Image_Box*> (oy_widget);
icc = oy_box->setImage( file_name, module_options );
}
}
if(icc || (gl_box & 0x04 && !error))
{
setWindowMenue( win, oy_widget, icc );
/* observe the node */
if(icc)
oy_widget->observeICC( icc, conversionObserve );
win->label( file_name );
}
win->show();
Fl::add_timeout(0.02, (void(*)(void*))jobResultRepeatCb);
Fl::run();
return 0;
}
#include <FL/Fl_Image.H>
static Fl_RGB_Image image_oyranos_logo(oyranos_logo, 64, 64, 4, 0);
struct box_n_opts {
Oy_Fl_Image_Widget * box;
};
int changeIccOptionsUpdate ( oyJob_s * job )
{
oyBlob_s * context = (oyBlob_s *) job->context;
struct box_n_opts * arg = (box_n_opts*) oyBlob_GetPointer( context );
#if 0
((Fl_Widget*)arg->box)->damage(FL_DAMAGE_ALL,arg->box->x(),arg->box->y(),arg->box->w(),arg->box->h());
arg->box->damage_resize(arg->box->x(),arg->box->y(),arg->box->w(),arg->box->h());
#else
arg->box->deactivate();
arg->box->activate();
#endif
return 0;
}
extern "C" {
int changeIccOptions ( oyJob_s * job )
{
oyBlob_s * context = (oyBlob_s *) job->context;
struct box_n_opts * arg = (box_n_opts*) oyBlob_GetPointer( context );
oyStruct_s * object = (oyStruct_s*) arg->node;
{
oyFilterNode_s * node = (oyFilterNode_s*) object;
oyOptions_s * opts = 0,
* new_opts = 0;
const char * tmp_dir = getenv("TMPDIR"),
* in_text = 0,
* model = 0;
char * command = new char [1024];
char * t = 0;
int error = 0;
char * ui_text = 0, ** namespaces = 0;
if(!tmp_dir)
tmp_dir = "/tmp";
error = oyFilterNode_GetUi( node, &ui_text, &namespaces, malloc );
model = oyOptions_GetText( opts, oyNAME_NAME );
in_text= oyXFORMsFromModelAndUi( model, ui_text, (const char**)namespaces,0,
malloc );
/* export the options values */
sprintf( command, "%s/image_display_in_tmp.xml", tmp_dir );
oyWriteMemToFile_( command, in_text, strlen(in_text) );
in_text = 0; command[0] = 0;
/* render the options to the UI */
{
const char * uiRenderer = getenv("OY_OFORMS_RENDERER");
if(uiRenderer && uiRenderer[0])
sprintf(command, "%s ", uiRenderer );
else
if((uiRenderer = getenv("OY_XFORMS_RENDERER")) != NULL && uiRenderer[0])
sprintf(command, "%s ", uiRenderer );
else
sprintf(command, "oyranos-xforms-fltk " );
}
sprintf(&command[strlen(command)],
" -i %s/image_display_in_tmp.xml -o %s/image_display_tmp.xml",
tmp_dir, tmp_dir );
error = system(command);
if(error)
fprintf(stderr, "error %d for \"%s\"", error, command );
/* reload changed options */
t = strstr(command," -o ");
size_t size = 0;
char * opts_text = oyReadFileToMem_(t+4, &size, malloc);
new_opts = oyOptions_FromText( opts_text, 0, 0 );
free(opts_text);
oyOptions_CopyFrom( &opts, new_opts, oyBOOLEAN_UNION, oyFILTER_REG_NONE, 0);
/* TODO update the conversion context and enforce a redraw
* The context of a node can be removed to allow for updating.
* A redrawing flag should be obtainable from the graph.
*/
arg->box->damage( FL_DAMAGE_USER1 );
delete [] command;
}
return 0;
}
void jobCallback ( double progress_zero_till_one,
char * status_text,
int thread_id_,
int job_id,
oyStruct_s * cb_progress_context )
{ printf( "%s():%d %02f %s %d/%d\n",__func__,__LINE__,progress_zero_till_one,
status_text?status_text:"",thread_id_,job_id); }
}
void callback ( Fl_Widget* w, void* daten )
{
struct box_n_opts * arg = (box_n_opts*) daten;
oyStruct_s * object = (oyStruct_s*) arg->node;
oyBlob_s * context = oyBlob_New(0);
oyBlob_SetFromStatic( context, arg, 0, "struct box_n_opts" );
if(!w->parent())
printf("Could not find parents.\n");
else
if(!object)
printf("Oyranos argument missed.\n");
else
if(object && object->type_ == oyOBJECT_FILTER_NODE_S)
{
oyJob_s * job = oyJob_New(0);
job->work = changeIccOptions;
job->finish = changeIccOptionsUpdate;
job->context = (oyStruct_s*)context;
job->cb_progress = jobCallback;
oyJob_Add(&job, 0);
} else
printf("could not find a suitable program structure\n");
}
void view_cb ( Fl_Widget* w, void* daten )
{
struct box_n_opts * arg = (box_n_opts*) daten;
oyStruct_s * object = (oyStruct_s*) arg->node;
if(!w->parent())
printf("Could not find parents.\n");
else
if(!object)
printf("Oyranos argument missed.\n");
else
if(object && object->type_ == oyOBJECT_FILTER_NODE_S)
{
int error = 0;
oyConversion_s * cc = arg->box->conversion();
oyFilterNode_s * in = oyConversion_GetNode( cc, OY_INPUT);
const char * fn = oyOptions_FindString( opts, "//" OY_TYPE_STD "/file_read/filename", 0 );
char * command = new char [1024];
if(!fn)
{
oyImage_s * image = oyConversion_GetImage( cc, OY_INPUT );
opts = oyImage_GetTags(image);
fn = oyOptions_FindString( opts, "//" OY_TYPE_STD "/file_read/filename", 0 );
oyImage_Release( &image );
}
/* export the options values */
sprintf( command, "iccexamin -g \"%s\" &", fn );
error = system(command);
if(error)
fprintf(stderr, "error %d for \"%s\"", error, command );
if(command) delete [] command;
}
else
printf("could not find a suitable program structure\n");
}
void dbg_cb ( Fl_Widget* w, void* daten )
{
struct box_n_opts * arg = (box_n_opts*) daten;
oyStruct_s * object = (oyStruct_s*) arg->node;
if(!w->parent())
printf("Could not find parents.\n");
else
if(!object)
printf("Oyranos argument missed.\n");
else
if(object && object->type_ == oyOBJECT_FILTER_NODE_S)
{
if(idcc)
idcc = arg->box->conversion();
int oy_debug_old = oy_debug;
oy_debug = 1;
oyShowConversion_(idcc, 0);
oy_debug = oy_debug_old;
oyImage_s * image = oyConversion_GetImage( idcc, OY_INPUT );
oyImage_WritePPM( image, "debug_image.ppm", "image_display input image");
oyImage_Release( &image );
oyFinish_( FINISH_IGNORE_I18N | FINISH_IGNORE_CACHES );
}
}
Oy_Fl_Double_Window * make_help(const char * title, const char * text, int is_html)
{
Oy_Fl_Double_Window * help_window=(Oy_Fl_Double_Window *)0;
Fl_Text_Display * text_display=(Fl_Text_Display *)0;
Fl_Help_View * help_browser=(Fl_Help_View *)0;
{ help_window = new Oy_Fl_Double_Window(505, 410, title?title:_("Information:"));
help_window->box(FL_FLAT_BOX);
help_window->color(FL_BACKGROUND_COLOR);
help_window->selection_color(FL_BACKGROUND_COLOR);
help_window->labeltype(FL_NO_LABEL);
help_window->labelfont(0);
help_window->labelsize(14);
help_window->labelcolor(FL_FOREGROUND_COLOR);
help_window->align(Fl_Align(FL_ALIGN_TOP));
help_window->when(FL_WHEN_RELEASE);
if(is_html)
{ help_browser = new Fl_Help_View(0, 0, 505, 410);
help_browser->box(FL_THIN_UP_BOX);
help_browser->color((Fl_Color)16);
Fl_Group::current()->resizable(help_browser);
} // Fl_Help_View* help_browser
else
{ Fl_Text_Display* o = text_display = new Fl_Text_Display(0, 0, 505, 410);
Fl_Text_Buffer * buffer = new Fl_Text_Buffer(0);
o->buffer( buffer );
//o->textfont( FL_COURIER );
o->box(FL_THIN_UP_BOX);
//o->box( FL_FLAT_BOX );
o->color(FL_BACKGROUND_COLOR);
Fl_Group::current()->resizable(o);
}
help_window->end();
} // Oy_Fl_Double_Window* help_window
help_window->show();
if(text)
{
if(is_html)
help_browser->value( text );
else
text_display->buffer()->text( text );
}
return help_window;
}
void help_cb ( Fl_Widget*, void* )
{
const char * opts[] = {"add_html_header","1",
"add_oyranos_title","1",
"add_oyranos_copyright","1",
NULL};
int is_html = 1;
make_help( _("Oyranos Help"), oyDescriptionToHTML(oyGROUP_ALL, opts,0), is_html );
}
void shortcuts_cb ( Fl_Widget*, void* )
{
char * html = NULL;
oyStringAddPrintf( &html,0,0,
"<html><body>"
"<h4>%s</h4>"
"<ul>"
"<li>%s</li>"
"<li>%s</li>"
"</ul>"
"<h4>%s</h4>"
"<ul>"
"<li>%s</li>"
"<li>%s</li>"
"<li>%s</li>"
"<li>%s</li>"
"<li>%s</li>"
"<li>%s</li>"
"</ul>"
"<h4>%s</h4>"
"<ul>"
"<li>%s</li>"
"<li>%s</li>"
"<li>%s</li>"
"</ul>"
"<h4>%s</h4>"
"<ul>"
"<li>%s</li>"
"<li>%s</li>"
"<li>%s</li>"
"<li>%s</li>"
"</ul>"
"<h4>%s</h4>"
"<ul>"
"<li>%s</li>"
"</ul>"
"</body></html>",
_("Navigation:"),
/* '>' */
_("&gt; - next image"),
/* '<' */
_("&lt; - previous image"),
_("Zoom:"),
_("f - fit to window"),
_("1 - map one image pixel to one screen pixel"),
_("w - fit to window width"),
_("h - fit to window height"),
_("+ - zoom in"),
_("- - zoom out"),
_("Exposure:"),
_("Alt + - brighter"),
_("Alt - - darker"),
_("Alt . - reset to normal values"),
_("Channels:"),
_("Alt 1 - first channel"),
_("Alt 2 - second channel"),
_("Alt n - n-th channel"),
_("Alt 0 - all channels"),
_("View:"),
_("Alt v - set window fullscreen")
);
int is_html = 1;
make_help( _("Oyranos Image Display Help"),
html,
is_html );
}
void info_cb ( Fl_Widget* w, void* daten )
{
struct box_n_opts * arg = (box_n_opts*) daten;
oyStruct_s * object = (oyStruct_s*) arg->node;
if(!w->parent())
printf("Could not find parents.\n");
else
if(!object)
printf("Oyranos argument missed.\n");
else
if(object && object->type_ == oyOBJECT_FILTER_NODE_S)
{
oyConversion_s * cc = arg->box->conversion();
oyFilterNode_s * in = oyConversion_GetNode( cc, OY_INPUT);
const char * fn = oyOptions_FindString( opts, "//" OY_TYPE_STD "/file_read/filename", 0 );
char * text = NULL;
const char * image_text = NULL;
size_t size = 0;
if(!fn)
{
oyImage_s * image = oyConversion_GetImage( cc, OY_INPUT );
opts = oyImage_GetTags(image);
fn = oyOptions_FindString( opts, "//" OY_TYPE_STD "/file_read/filename", 0 );
image_text = oyObject_GetName( image->oy_, oyNAME_NICK );
oyImage_Release( &image );
}
if(oyFindApplication("tiffinfo"))
text = oyReadCmdToMemf_( &size, "r", malloc, "tiffinfo \"%s\"", fn );
if((!text || text[0] == 0) && oyFindApplication("file"))
text = oyReadCmdToMemf_( &size, "r", malloc, "file \"%s\"", fn );
oyStringAdd_( &text, "\n", oyAllocateFunc_, oyDeAllocateFunc_ );
oyStringAdd_( &text, image_text, oyAllocateFunc_, oyDeAllocateFunc_ );
make_help( _("Oyranos Image Display Info"), text, 0 );
}
else
printf("could not find a suitable program structure\n");
}
void exit_cb ( Fl_Widget* w, void* daten )
{
oy_widget->conversion(NULL);
if(oy_debug_objects >= 0)
oyObjectTreePrint( 0x01 | 0x02 );
exit(0);
}
Oy_Fl_Double_Window * createWindow (Oy_Fl_Image_Widget ** oy_box, uint32_t flags)
{
int w = 640,
h = 480,
lh = 1;
if(flags & 0x02)
lh = 100;
Fl::get_system_colors();
Oy_Fl_Double_Window *win = new Oy_Fl_Double_Window( w, h+lh, "Oyranos" );
Fl_Tile* t;
if(flags & 0x02)
t = new Fl_Tile(0,0, w, h+lh);
if(flags & 0x04)
*oy_box = new Oy_Fl_Shader_Box(0,0,w,h);
else if(flags & 0x01)
*oy_box = new Oy_Fl_GL_Box(0,0,w,h);
else
*oy_box = new Oy_Fl_Image_Box(0,0,w,h);
(*oy_box)->box(FL_FLAT_BOX);
if(flags & 0x02)
{
t->resizable(*oy_box);
oyProfile_s * e = NULL; /* default: sRGB */
Oy_Fl_Group * og = lg = new Oy_Fl_Group(0, h, w, lh, e);
int gh = h;
if(flags & 0x02)
{
/* add some text */
Fl_Box *box = new Fl_Box(0,0+gh,w,100, "Oyranos");
box->labeltype(FL_ENGRAVED_LABEL);
box->labelfont(0);
box->labelsize(48);
box->labelcolor(FL_FOREGROUND_COLOR);
box->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
box->box(FL_FLAT_BOX);
og->resizable(box);
}
/* place the color managed logo */
{
Fl_Box* o = new Fl_Box(16, 16+gh, 64, 64);
o->image(image_oyranos_logo);
o->color(FL_RED);
o->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
}
og->end();
t->end();
Fl_Group::current()->resizable(t);
}
else
win->resizable(*oy_box);
win->end();
return win;
}
oyOptions_s * findOpts( const char * filter_name )
{
oyFilterNode_s * n = oyFilterGraph_GetNode( g, -1, filter_name, NULL );
return opts;
}
oyOption_s * findOpt( const char * filter_name, const char * key_name )
{
oyFilterNode_s * n = oyFilterGraph_GetNode( g, -1, filter_name, NULL );
oyOption_s * opt = oyOptions_Find( opts, key_name, oyNAME_PATTERN );
return opt;
}
/* Prepare a JSON complying string for the channel filter.
* The string describes the source of the output channels.
* e.g.: '["b", "b", "b"]'
*/
void setChannel( oyProfile_s * p, int channel_pos )
{
oyOptions_s * opts = findOpts( "//" OY_TYPE_STD "/channel" );
char * channels = NULL;
icColorSpaceSignature cs = (icColorSpaceSignature) oyProfile_GetSignature( p, oySIGNATURE_COLOR_SPACE );
int count = oyICCColorSpaceGetChannelCount( cs ), i;
if(channel_pos == 0 ||
channel_pos > count)
oyStringAddPrintf( &channels, 0,0, "" );
else
{
oyStringAddPrintf( &channels, 0,0, "[" );
for(i = 0; i < count; ++i)
{
if(i > 0)
oyStringAddPrintf( &channels, 0,0, ", " );
switch(cs)
{
case icSigLabData:
case icSigLuvData:
case icSigYCbCrData:
case icSigYxyData:
case icSigHsvData:
case icSigHlsData:
if(channel_pos-1 == i)
oyStringAddPrintf( &channels, 0,0, "\"%c\"", 'a' + channel_pos - 1 );
else
oyStringAddPrintf( &channels, 0,0, "0.5" );
break;
default:
oyStringAddPrintf( &channels, 0,0, "\"%c\"", 'a' + channel_pos - 1 );
}
}
oyStringAddPrintf( &channels, 0,0, "]" );
}
oyOptions_SetFromText( &opts, "//" OY_TYPE_STD "/channel/channel", channels, OY_CREATE_NEW );
oyDeAllocateFunc_( channels );
}
char ** getFileList(const char * path, int * count, const char * file, int * pos )
{
int i;
char * fn = NULL;
// Special case for file name with path. Then search in local "./" place.
if(!path || path[0] == 0)
path = ".";
if(path && file && strlen(path) == 1 && path[0] == '.' &&
strchr(file,OY_SLASH_C) == NULL && strchr(file,'\\') == NULL)
oyStringAddPrintf( &fn, 0,0, "./%s", file );
char ** files = oyGetFiles_( path, count );
if(file && pos)
for(i = 0; i < *count; ++i)
{
if(strcmp( files[i], fn?fn:file ) == 0)
{
*pos = i;
break;
}
}
return files;
}
const char * scale_reg = OY_INTERNAL OY_SLASH "scale/scale";
const char * scales_reg = OY_INTERNAL OY_SLASH "scale";
char * path = 0;
void openNextImage ( Oy_Fl_Image_Widget* oy_widget,
int increment )
{
int pos = 0, count = 0;
oyConversion_s * cc = oy_widget->conversion();
oyImage_s * image = oyConversion_GetImage( cc, OY_INPUT );
oyOptions_s * tags = oyImage_GetTags( image );
const char * filename = oyOptions_FindString( tags,
"//" OY_TYPE_STD "/file_read/filename",
0 );
if(!path)
path = oyExtractPathFromFileName_( filename );
char ** files = getFileList( path, &count, filename, &pos );
oyImage_Release( &image );
oyOptions_s * module_options = oyFilterNode_GetOptions( icc, 0 );
Oy_Fl_GL_Box * oy_box = dynamic_cast<Oy_Fl_GL_Box*> (oy_widget);
if(oy_box)
{
for(int i = 0; i < count; ++i)
{
pos += increment;
if(pos >= count)
pos = 0;
else if(pos < 0)
pos = count - 1;
if(strstr(files[pos],".xvpics") != NULL ||
strstr(files[pos],".thumbnails") != NULL)
continue;
if(oy_display_verbose)
fprintf( stderr, "open image %s %d/%d\n", files[pos], i, count );
icc = oy_box->setImage( files[pos], module_options );
if(icc)
{
setWindowMenue( win, oy_widget, icc );
/* observe the node */
oy_widget->observeICC( icc, conversionObserve );
win->label( files[pos] );
break;
} else if(oy_display_verbose)
fprintf( stderr, "could not open image %s; continuing with next. %d/%d\n", files[pos], i, count );
fflush( stderr );
Fl::wait(0);
}
} else
fprintf(stderr, "need a GL box; skipping image change ...\n");
oyOptions_Release( &module_options );
oyStringListRelease_( &files, count, oyDeAllocateFunc_ );
oy_widget->damage( FL_DAMAGE_USER1 );
}
void setFullscreen()
{
static int fullscreen = 0, x,y,w,h;
if(fullscreen)
{
oy_widget->window()->fullscreen_off(x,y,w,h);
fullscreen = 0;
} else
{
x = oy_widget->window()->x();
y = oy_widget->window()->y();
w = oy_widget->window()->w();
h = oy_widget->window()->h();
oy_widget->window()->fullscreen();
fullscreen = 1;
}
}
int
event_handler(int e)
{
int found = 0;
oyOptions_s * opts;
switch (e)
{
case FL_SHORTCUT:
{
int k = Fl::event_key();
double expose = 1.0;
if(Fl::event_key() == FL_Escape)
{
exit(0);
found = 1;
}
if(k == FL_F + 11)
setFullscreen();
if(Fl::event_state() & FL_ALT ||
Fl::event_state() & FL_META)
switch (k)
{
case 'q':
exit(0);
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
oyConversion_s * cc = oy_widget->conversion();
oyImage_s * image = oyConversion_GetImage( cc, OY_INPUT );
oyProfile_s * profile = oyImage_GetProfile( image );
setChannel( profile, k - '0' );
oyImage_Release( &image );
oyProfile_Release( &profile );
}
found = 1;
break;
case '-':
found = 1;
opts = findOpts( "//" OY_TYPE_STD "/expose" );
"expose",
0, &expose );
expose /= M_SQRT2;
"//" OY_TYPE_STD "/expose/expose",
expose, 0, OY_CREATE_NEW );
oy_widget->damage( FL_DAMAGE_USER1 );
break;
case '+': // 43
found = 1;
opts = findOpts( "//" OY_TYPE_STD "/expose" );
"expose",
0, &expose );
expose *= M_SQRT2;
"//" OY_TYPE_STD "/expose/expose",
expose, 0, OY_CREATE_NEW );
oy_widget->damage( FL_DAMAGE_USER1 );
break;
case '.':
found = 1;
opts = findOpts( "//" OY_TYPE_STD "/expose" );
"expose",
0, &expose );
expose = 1.0;
"//" OY_TYPE_STD "/expose/expose",
expose, 0, OY_CREATE_NEW );
oy_widget->damage( FL_DAMAGE_USER1 );
break;
case 'v':
setFullscreen();
found = 1;
break;
}
}
case FL_KEYBOARD:
{
int k = ((char*)Fl::event_text())[0];
double scale = 1.0;
oyOption_s * opt = 0;
if(!(Fl::event_state() & FL_ALT ||
Fl::event_state() & FL_META))
switch (k)
{
case '-':
found = 1;
opt = findOpt( scales_reg, scale_reg );
scale = oyOption_GetValueDouble( opt, 0 );
scale /= oy_widget->scale_changer;
// scale relative to the middle of the image
oy_widget->px = int((double)(oy_widget->px - oy_widget->w()/2) / oy_widget->scale_changer) + oy_widget->w()/2;
oy_widget->py = int((double)(oy_widget->py - oy_widget->h()/2) / oy_widget->scale_changer) + oy_widget->h()/2;
oy_widget->resetScale();
oyOption_SetFromDouble( opt, scale, 0,0 );
break;
case '+': // 43
found = 1;
opt = findOpt( scales_reg, scale_reg );
scale = oyOption_GetValueDouble( opt, 0 );
scale *= oy_widget->scale_changer;
// scale relative to the middle of the image
oy_widget->px = int((double)(oy_widget->px - oy_widget->w()/2) * oy_widget->scale_changer) + oy_widget->w()/2;
oy_widget->py = int((double)(oy_widget->py - oy_widget->h()/2) * oy_widget->scale_changer) + oy_widget->h()/2;
oy_widget->resetScale();
oyOption_SetFromDouble( opt, scale, 0,0 );
break;
case '*':
found = 1;
oy_widget->scale_changer += (oy_widget->scale_changer-1.0)*.2;
break;
case '/':
found = 1;
oy_widget->scale_changer -= (oy_widget->scale_changer-1.0)*.2;
break;
case 'h':
opt = findOpt( scales_reg, scale_reg );
{
oyConversion_s * cc = oy_widget->conversion();
oyImage_s * image = oyConversion_GetImage( cc, OY_INPUT );
double widget_height = oy_widget->h(),
image_height = oyImage_GetHeight( image ),
old_scale = scale;
old_scale = oyOption_GetValueDouble( opt, 0 );
scale = widget_height/image_height;
/* reset position to zero */
oy_widget->px = int((double)oy_widget->px / old_scale * scale);
oy_widget->py = 0;
oyImage_Release( &image );
}
found = 1;
oy_widget->resetScale();
oyOption_SetFromDouble( opt, scale, 0,0 );
break;
case 'w':
opt = findOpt( scales_reg, scale_reg );
{
oyConversion_s * cc = oy_widget->conversion();
oyImage_s * image = oyConversion_GetImage( cc, OY_INPUT );
double widget_width = oy_widget->w(),
image_width = oyImage_GetWidth( image ),
old_scale = scale;
old_scale = oyOption_GetValueDouble( opt, 0 );
scale = widget_width/image_width;
/* reset position to zero */
oy_widget->px = int((double)oy_widget->px / old_scale * scale);
oy_widget->py = 0;
oyImage_Release( &image );
}
found = 1;
oy_widget->resetScale();
oyOption_SetFromDouble( opt, scale, 0,0 );
break;
case '0': /* image ==> window size */
case 'f': /* fit window */
{
oyConversion_s * cc = oy_widget->conversion();
oyImage_s * image = oyConversion_GetImage( cc, OY_INPUT );
double widget_width = oy_widget->w(),
widget_height = oy_widget->h(),
image_height = oyImage_GetHeight( image ),
image_width = oyImage_GetWidth( image );
if(widget_width/image_width < widget_height/image_height)
scale = widget_width/image_width;
else
scale = widget_height/image_height;
/* reset position to zero */
oy_widget->px = 0;
oy_widget->py = 0;
oyImage_Release( &image );
}
found = 1;
opt = findOpt( scales_reg, scale_reg );
oy_widget->resetScale();
oyOption_SetFromDouble( opt, scale, 0,0 );
break;
case '1': /* pixel size */
scale = 1.0;
found = 1;
opt = findOpt( scales_reg, scale_reg );
oy_widget->resetScale();
oyOption_SetFromDouble( opt, scale, 0,0 );
break;
case '<':
openNextImage(oy_widget, -1);
found = 1;
break;
case '>':
openNextImage(oy_widget, +1);
found = 1;
break;
default:
break;
}
if(opt)
/* store to DB */
{
char * d = 0;
int error;
double dv = scale;
if(k == 'f' || k == '0')
dv = -1;
else if(k == 'w')
dv = -2;
else if(k == 'h')
dv = -3;
oyStringAddPrintf( &d, 0,0, "%g", dv );
error = oySetPersistentString( scale_reg, oySCOPE_USER, d, 0 );
printf("%d saved key to DB\n", error);
oyFree_m_( d );
}
}
break;
default:
break;
}
return found;
}
void setWindowMenue ( Oy_Fl_Double_Window * win,
Oy_Fl_Image_Widget * oy_box,
oyFilterNode_s * node )
{
struct box_n_opts * arg = new box_n_opts;
win->begin();
Fl_Menu_Button *menue_;
Fl_Menu_Button *menue_button_;
menue_button_ = new Fl_Menu_Button(0,0,win->w(),win->h(),0);
menue_button_->type(Fl_Menu_Button::POPUP3);
menue_button_->box(FL_NO_BOX);
menue_button_->clear();
menue_ = new Fl_Menu_Button(0,0,win->w(),win->h(),""); menue_->hide();
arg->node = node;
arg->box = oy_box;
if(node)
{
menue_->add( _("Edit Options ..."),
FL_CTRL + 'e', callback, (void*)arg, 0 );
menue_->add( _("Examine ICC Profile ..."),
FL_CTRL + 'i', view_cb, (void*)arg, 0 );
menue_->add( _("Debug"),
FL_CTRL + 'd', dbg_cb, (void*)arg, 0 );
menue_->add( _("Show Infos"),
FL_CTRL + 'f', info_cb, (void*)arg, 0 );
}
menue_->add( _("Help Shortcuts"),
FL_CTRL + 'h', shortcuts_cb, (void*)arg, 0 );
menue_->add( _("Help"),
FL_F + 1, help_cb, (void*)arg, 0 );
menue_->add( _("Quit"),
FL_CTRL + 'q', exit_cb, (void*)arg, 0 );
menue_button_->copy(menue_->menu());
Fl::add_handler(event_handler);
win->end();
}
oyProfile_s::oyProfile_GetSignature
OYAPI icSignature OYEXPORT oyProfile_GetSignature(oyProfile_s *profile, oySIGNATURE_TYPE_e type)
Get ICC color space signature.
Definition: oyProfile_s.c:865
oyProfiles_s.h
oyImage_s::oyImage_GetProfile
oyProfile_s * oyImage_GetProfile(oyImage_s *image)
Get the image profile.
Definition: oyImage_s.c:1531
oyOption_s::oyOption_Release
OYAPI int OYEXPORT oyOption_Release(oyOption_s **option)
release and possibly deallocate a oyOption_s object
Definition: oyOption_s.c:87
oySetPersistentString
int oySetPersistentString(const char *key_name, oySCOPE_e scope, const char *value, const char *comment)
set string into DB and cache
Definition: oyranos_texts.c:2281
oyFilterGraph_s
A FilterGraph object.
Definition: oyFilterGraph_s.h:61
oyProfiles_s::oyProfiles_New
OYAPI oyProfiles_s *OYEXPORT oyProfiles_New(oyObject_s object)
allocate a new Profiles object
Definition: oyProfiles_s.c:41
oyConversion_s::oyConversion_GetImage
oyImage_s * oyConversion_GetImage(oyConversion_s *conversion, uint32_t flags)
Get a image copy at the desired position.
Definition: oyConversion_s.c:500
oyFilterNode_s::oyFilterNode_GetOptions
oyOptions_s * oyFilterNode_GetOptions(oyFilterNode_s *node, int flags)
Get filter options.
Definition: oyranos_devices.c:2527
oyObject_GetName
const oyChar * oyObject_GetName(const oyObject_s obj, oyNAME_e type)
object get names
Definition: oyObject_s.c:424
oyOptions_s::oyOptions_FromText
oyOptions_s * oyOptions_FromText(const char *text, uint32_t flags, oyObject_s object)
deserialise a text file to oyOptions_s data
Definition: oyOptions_s.c:532
oyFilterNode_s::oyFilterNode_GetUi
int oyFilterNode_GetUi(oyFilterNode_s *node, char **ui_text, char ***namespaces, oyAlloc_f allocateFunc)
Get filter options XFORMS.
Definition: oyranos_devices.c:2582
oyOption_s
Option object.
Definition: oyOption_s.h:148
oyOptions_s::oyOptions_MoveInStruct
int oyOptions_MoveInStruct(oyOptions_s **obj, const char *registration, oyStruct_s **oy_struct, uint32_t flags)
change a value
Definition: oyOptions_s.c:1876
oyBlob_s::oyBlob_New
OYAPI oyBlob_s *OYEXPORT oyBlob_New(oyObject_s object)
allocate a new Blob object
Definition: oyBlob_s.c:35
oyOptions_s::oyOptions_SetFromText
int oyOptions_SetFromText(oyOptions_s **obj, const char *registration, const char *value, uint32_t flags)
change a value
Definition: oyOptions_s.c:1514
oyConversion_s::oyConversion_GetNode
oyFilterNode_s * oyConversion_GetNode(oyConversion_s *conversion, uint32_t flags)
Get the filter node copy.
Definition: oyConversion_s.c:579
oyNAME_PATTERN
#define oyNAME_PATTERN
a logical name for registration search
Definition: oyranos.h:149
oyFilterGraph_s::oyFilterGraph_Release
OYAPI int OYEXPORT oyFilterGraph_Release(oyFilterGraph_s **filtergraph)
release and possibly deallocate a oyFilterGraph_s object
Definition: oyFilterGraph_s.c:89
OY_TYPE_STD
#define OY_TYPE_STD
Definition: oyranos_definitions.h:118
oyObjectTreePrint
void oyObjectTreePrint(int flags)
Print the current object trees to stderr.
Definition: oyranos_tree.c:742
oyImage_s::oyImage_GetWidth
int oyImage_GetWidth(oyImage_s *image)
Get the width in pixel.
Definition: oyImage_s.c:1426
oyJob_s::finish
int(* finish)(oyJob_s *job)
the observating thread callback
Definition: oyranos_threads.h:55
oyImage_s::oyImage_GetTags
oyOptions_s * oyImage_GetTags(oyImage_s *image)
Get object tags.
Definition: oyImage_s.c:1553
oyJob_s::work
int(* work)(oyJob_s *job)
the working thread callback
Definition: oyranos_threads.h:53
OY_SELECT_FILTER
#define OY_SELECT_FILTER
select from filter
Definition: oyranos_object.h:215
oyJob_s::oyJob_Add
oyJob_Add_f oyJob_Add
Add one unique oyJob_s to the job qeue.
Definition: oyranos_threads.c:161
oyJob_s::cb_progress
oyJobCallback_f cb_progress
the progress callback, called by observating thread
Definition: oyranos_threads.h:56
oyProfile_s::oyProfile_Release
OYAPI int OYEXPORT oyProfile_Release(oyProfile_s **profile)
release and possibly deallocate a oyProfile_s object
Definition: oyProfile_s.c:89
oySIGNATURE_COLOR_SPACE
@ oySIGNATURE_COLOR_SPACE
Definition: oyranos_profile.h:69
oyOptions_s::oyOptions_CopyFrom
int oyOptions_CopyFrom(oyOptions_s **list, oyOptions_s *from, oyBOOLEAN_e type, oyFILTER_REG_e fields, oyObject_s object)
copy from one option set to an other option set
Definition: oyOptions_s.c:839
oyGROUP_ALL
@ oyGROUP_ALL
Definition: oyranos.h:78
OY_DEFAULT_CMM_CONTEXT
#define OY_DEFAULT_CMM_CONTEXT
Definition: oyranos_definitions.h:209
oyOPTIONATTRIBUTE_ADVANCED
@ oyOPTIONATTRIBUTE_ADVANCED
Definition: oyranos_object.h:258
oyOBJECT_FILTER_NODE_S
@ oyOBJECT_FILTER_NODE_S
Definition: oyranos_object.h:154
oyImage_s::oyImage_GetHeight
int oyImage_GetHeight(oyImage_s *image)
Get the width in pixel.
Definition: oyImage_s.c:1446
oyProfiles_s::oyProfiles_MoveIn
OYAPI int OYEXPORT oyProfiles_MoveIn(oyProfiles_s *list, oyProfile_s **obj, int pos)
add an element to a Profiles list
Definition: oyProfiles_s.c:117
oyStruct_s
Oyranos base structure.
Definition: oyStruct_s.h:78
oyOption_s::oyOption_GetValueDouble
double oyOption_GetValueDouble(oyOption_s *obj, int pos)
get a double
Definition: oyOption_s.c:584
oyOptions_s
generic Options
Definition: oyOptions_s.h:80
oyranos_threads.h
thread methods
oyAlloc_f
void *(* oyAlloc_f)(size_t size)
Definition: oyranos_types.h:71
oy_debug
int oy_debug
Set debug level.
Definition: oyranos_debug.c:72
OY_SLASH
#define OY_SLASH
Definition: oyranos_definitions.h:106
oyBlob_s::oyBlob_GetPointer
oyPointer oyBlob_GetPointer(oyBlob_s *blob)
get value from a data blob
Definition: oyBlob_s.c:214
oyFilterNode_s::oyFilterNode_Release
OYAPI int OYEXPORT oyFilterNode_Release(oyFilterNode_s **filternode)
release and possibly deallocate a oyFilterNode_s object
Definition: oyFilterNode_s.c:97
oyConversion_s::oyConversion_Release
OYAPI int OYEXPORT oyConversion_Release(oyConversion_s **conversion)
release and possibly deallocate a oyConversion_s object
Definition: oyConversion_s.c:93
oyFilterGraph_s::oyFilterGraph_FromNode
OYAPI oyFilterGraph_s *OYEXPORT oyFilterGraph_FromNode(oyFilterNode_s *node, int flags)
Get a graphs adjazency list.
Definition: oyFilterGraph_s.c:122
oyJob_s::oyJobResult
oyJobResult_f oyJobResult
Poll for new Jobs.
Definition: oyranos_threads.c:212
oyFilterGraph_s::oyFilterGraph_GetNode
OYAPI oyFilterNode_s *OYEXPORT oyFilterGraph_GetNode(oyFilterGraph_s *graph, int pos, const char *registration, const char *mark)
Select a node.
Definition: oyFilterGraph_s.c:157
oySCOPE_USER
@ oySCOPE_USER
Definition: oyranos.h:49
oyStruct_s::type_
const oyOBJECT_e type_
Type of object.
Definition: oyStruct_s.h:80
oyOptions_s::oyOptions_Release
OYAPI int OYEXPORT oyOptions_Release(oyOptions_s **options)
release and possibly deallocate a oyOptions_s object
Definition: oyOptions_s.c:91
oyranos.h
The API header for general users to include in your application.
oyBlob_s::oyBlob_SetFromStatic
int oyBlob_SetFromStatic(oyBlob_s *blob, const oyPointer ptr, size_t size, const char *type)
set value from a data blob
Definition: oyBlob_s.c:173
oyOptions_s::oyOptions_FindString
const char * oyOptions_FindString(oyOptions_s *options, const char *registration, const char *value)
search for a certain option key and possibly value
Definition: oyOptions_s.c:1441
oyNAME_NICK
@ oyNAME_NICK
Definition: oyranos_core.h:73
oyConversion_s.h
oyOptions_s::oyOptions_Find
oyOption_s * oyOptions_Find(oyOptions_s *options, const char *registration, uint32_t type)
search for a certain option key
Definition: oyOptions_s.c:1379
oyOptions_s::oyOptions_FindDouble
int oyOptions_FindDouble(oyOptions_s *options, const char *registration, int pos, double *result)
get a value
Definition: oyOptions_s.c:1698
oyImage_s::oy_
oyObject_s oy_
Oyranos internal object.
Definition: oyImage_s.h:220
oyProfile_s::oyProfile_FromName
OYAPI oyProfile_s *OYEXPORT oyProfile_FromName(const char *name, uint32_t flags, oyObject_s object)
Create from name.
Definition: oyProfile_s.c:286
oyFilterNode_s
A FilterNode object.
Definition: oyFilterNode_s.h:155
oyProfile_s
A profile and its attributes.
Definition: oyProfile_s.h:95
OY_INTERNAL
#define OY_INTERNAL
Definition: oyranos_definitions.h:123
oyNAME_NAME
@ oyNAME_NAME
Definition: oyranos_core.h:70
oyBlob_s
A data blob object.
Definition: oyBlob_s.h:59
oyICCProfileSelectionFlagsFromRegistration
uint32_t oyICCProfileSelectionFlagsFromRegistration(const char *registration)
Get flags for oyProfile_FromFile() and friends.
Definition: oyranos_texts.c:2090
oyProfiles_s
Tell about the conversion profiles.
Definition: oyProfiles_s.h:69
oyJob_s::oyJob_New
oyJob_New
Allocate a new oyJob_s object.
OY_PROFILES_EFFECT
#define OY_PROFILES_EFFECT
Definition: oyranos_definitions.h:231
oyJob_s::context
oyStruct_s * context
the workload
Definition: oyranos_threads.h:52
oyImage_s
A reference struct to gather information for image transformation.
Definition: oyImage_s.h:215
oyImage_s::oyImage_Release
OYAPI int OYEXPORT oyImage_Release(oyImage_s **image)
release and possibly deallocate a oyImage_s object
Definition: oyImage_s.c:82
oyOptions_s::oyOptions_SetFromDouble
int oyOptions_SetFromDouble(oyOptions_s **obj, const char *registration, double value, int pos, uint32_t flags)
change a value
Definition: oyOptions_s.c:1752
OY_SLASH_C
#define OY_SLASH_C
Definition: oyranos_definitions.h:108
OY_DEFAULT_EFFECT
#define OY_DEFAULT_EFFECT
Definition: oyranos_definitions.h:204
oyJob_s
Asynchron job ticket.
Definition: oyranos_threads.h:46
oyICCColorSpaceGetChannelCount
int oyICCColorSpaceGetChannelCount(icColorSpaceSignature color)
number of channels in a color space
Definition: oyranos_icc.c:52
oyOptions_s::oyOptions_GetText
const char * oyOptions_GetText(oyOptions_s *options, oyNAME_e type)
dump options to text
Definition: oyOptions_s.c:1086
oyImage_s::oyImage_WritePPM
oyImage_WritePPM
write buffer to portable pix map format
oyOption_s::oyOption_SetFromDouble
int oyOption_SetFromDouble(oyOption_s *obj, double floating_point, int pos, uint32_t flags)
set a double value
Definition: oyOption_s.c:483
oyBOOLEAN_UNION
@ oyBOOLEAN_UNION
Definition: oyranos_object.h:278
oyConversion_s
A filter chain or graph to manipulate a image.
Definition: oyConversion_s.h:184
OY_CREATE_NEW
#define OY_CREATE_NEW
Definition: oyOptions_s.h:52