/** * @memberof oyFilterNode_s * @brief Set module data * @internal * * the filters private data, requested over * oyCMMapi4_s::oyCMMFilterNode_ContextToMem() and converted to * oyCMMapi4_s::context_type * * Oyranos' core provides that data. See oyFilterNode_ToBlob() * * @param[in,out] node filter object * @return the data * * @version Oyranos: 0.9.5 * @date 2013/12/22 * @since 2012/10/04 (Oyranos: 0.5.0) */ OYAPI int OYEXPORT oyFilterNode_SetContext ( oyFilterNode_s * node, oyPointer_s * data ) { oyFilterNode_s_ * s = (oyFilterNode_s_*)node; if(!node) return 0; oyCheckType__m( oyOBJECT_FILTER_NODE_S, return 1 ) oyPointer_Release( &s->backend_data ); s->backend_data = oyPointer_Copy( data, 0 ); return 0; }
/** * @memberof oyCMMapi4_s * @brief set filter type specific runtime data * * Runtime data can be used as context by a backend during execution. The data * is typical set during backend load. * * That data is apart from a filter object, which can have lifetime data * associated through a oyFilterNode_GetContext(). A filter connector * can have its processing data associated through oyFilterNode_SetData(). * * @param[in,out] api api object * @param[in] ptr the data needed to run the filter type * @return error * * @version Oyranos: 0.9.5 * @date 2013/12/19 * @since 2013/12/19 (Oyranos: 0.9.5) */ OYAPI int OYEXPORT oyCMMapi4_SetBackendContext ( oyCMMapi4_s * api, oyPointer_s * ptr ) { oyCMMapi4_s_ * s = (oyCMMapi4_s_*)api; int error = 0; if(!s) return -1; /* slightly fragile but inheritable */ oyCheckTypeRange_m( oyOBJECT_CMM_API4_S, oyOBJECT_CMM_API_MAX, return 1 ) { if(s->runtime_context) oyPointer_Release( &s->runtime_context ); s->runtime_context = oyPointer_Copy( ptr, NULL ); } return error; }
/** Function Configs_Modify * @brief oyCMMapi8_s SANE scanner manipulation * * @version Oyranos: 0.1.10 * @since 2009/01/19 (Oyranos: 0.1.10) * @date 2009/08/21 * * \todo { Test } */ int Configs_Modify(oyConfigs_s * devices, oyOptions_s * options) { oyOption_s *version_opt = NULL; oyOption_s *version_opt_dev = NULL; oyConfig_s *device = NULL; int num_devices, g_error = 0; int call_sane_exit = 0; const char *command_list = NULL, *command_properties = NULL; oyAlloc_f allocateFunc = malloc; printf(PRFX "Entering %s(). Options:\n%s", __func__, oyOptions_GetText(options, oyNAME_NICK)); /* "error handling" section */ if (!devices || !oyConfigs_Count(devices)) { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n " "No devices given! Options:\n%s", _DBG_ARGS_, oyOptions_GetText(options, oyNAME_NICK) ); return 1; } /* "help" call section */ if (oyOptions_FindString(options, "command", "help") || !options || !oyOptions_Count(options)) { /** oyMSG_WARN should make shure our message is visible. */ ConfigsFromPatternUsage((oyStruct_s *) options); return 0; } num_devices = oyConfigs_Count(devices); command_list = oyOptions_FindString(options, "command", "list"); command_properties = oyOptions_FindString(options, "command", "properties"); /* Now we get some options [IN], and we already have some devices with * possibly already assigned options. Those provided through the input * oyOptions_s should take presedence over ::data & ::backend_core ones. * OTOH, all device_* options have a 1-1 relationship meaning if * one changes, probably all other should. So the simplest [naive] approach * would be to ignore all device_* options [IN] that are already in device. * Except from driver_version which has a special meaning. */ /* Handle "driver_version" option [IN] */ /* Check the first device to see if a positive driver_version is provided. */ /* If not, consult the input options */ device = oyConfigs_Get(devices, 0); version_opt_dev = oyConfig_Find(device, "driver_version"); if (version_opt_dev && oyOption_GetValueInt(version_opt_dev, 0) > 0) call_sane_exit = 0; else check_driver_version(options, &version_opt, &call_sane_exit); oyConfig_Release(&device); oyOption_Release(&version_opt_dev); if (command_list) { /* "list" call section */ int i; for (i = 0; i < num_devices; ++i) { const SANE_Device *device_context = NULL; SANE_Status status = SANE_STATUS_INVAL; oyOption_s *name_opt_dev = NULL, *handle_opt_dev = NULL, *context_opt_dev = NULL; const char *sane_name = NULL, *sane_model = NULL; int error = 0; device = oyConfigs_Get(devices, i); if(oyOptions_Count(*oyConfig_GetOptions(device,"backend_core"))) printf(PRFX "Backend core:\n%s", oyOptions_GetText(*oyConfig_GetOptions(device,"backend_core"), oyNAME_NICK)); if(oyOptions_Count(*oyConfig_GetOptions(device,"data"))) printf(PRFX "Data:\n%s", oyOptions_GetText(*oyConfig_GetOptions(device,"data"), oyNAME_NICK)); /*Ignore device without a device_name*/ if (!oyOptions_FindString(*oyConfig_GetOptions(device,"backend_core"), "device_name", NULL)) { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n", _DBG_ARGS_, "The \"device_name\" is missing from config object!"); oyConfig_Release(&device); g_error++; continue; } /*Handle "driver_version" option [OUT] */ version_opt_dev = oyConfig_Find(device, "driver_version"); if (!version_opt_dev && version_opt) oyOptions_MoveIn(*oyConfig_GetOptions(device,"backend_core"), &version_opt, -1); oyOption_Release(&version_opt_dev); /*Handle "device_context" option */ /*This is always provided by Configs_FromPattern() * [or should be alternatively by the user]. * Configs_Modify() will not scan for SANE devices * because it takes too long*/ context_opt_dev = oyConfig_Find(device, "device_context"); if (!context_opt_dev) { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n", _DBG_ARGS_, "The \"device_context\" option is missing!"); error = g_error = 1; } if (!error) { device_context = (SANE_Device*)oyOption_GetData(context_opt_dev, NULL, allocateFunc); sane_name = device_context->name; sane_model = device_context->model; } /*Handle "oyNAME_NAME" option */ name_opt_dev = oyConfig_Find(device, "oyNAME_NAME"); if (!error && !name_opt_dev && oyOptions_Find(options, "oyNAME_NAME", oyNAME_PATTERN)) oyOptions_SetFromString(oyConfig_GetOptions(device,"backend_core"), CMM_BASE_REG OY_SLASH "oyNAME_NAME", sane_model, OY_CREATE_NEW); /*Handle "device_handle" option */ handle_opt_dev = oyConfig_Find(device, "device_handle"); if (!error && !handle_opt_dev) { oyPointer_s *handle_ptr = NULL; SANE_Handle h; status = sane_open(sane_name, &h); if (status == SANE_STATUS_GOOD) { handle_ptr = oyPointer_New(0); oyPointer_Set(handle_ptr, "SANE", "handle", (oyPointer)h, "sane_release_handle", sane_release_handle); oyOptions_MoveInStruct(oyConfig_GetOptions(device,"data"), CMM_BASE_REG OY_SLASH "device_handle", (oyStruct_s **) &handle_ptr, OY_CREATE_NEW); } else printf(PRFX "Unable to open sane device \"%s\": %s\n", sane_name, sane_strstatus(status)); } /*Create static rank_map, if not already there*/ if (!oyConfig_GetRankMap( device)) oyConfig_SetRankMap( device, _api8.rank_map ); /*Cleanup*/ oyConfig_Release(&device); oyOption_Release(&context_opt_dev); oyOption_Release(&name_opt_dev); oyOption_Release(&handle_opt_dev); } } else if (command_properties) { /* "properties" call section */ int i; /*Return a full list of scanner H/W & * SANE driver S/W color options * with the according rank map */ for (i = 0; i < num_devices; ++i) { SANE_Device *device_context = NULL; SANE_Status status = SANE_STATUS_INVAL; SANE_Handle device_handle; oyOption_s *name_opt_dev = NULL, *handle_opt_dev = NULL, *context_opt_dev = NULL; oyConfig_s *device_new = NULL; char *device_name = NULL; /* All previous device properties are considered obsolete * and a new device is created. Basic options are moved from * the old to new device */ device = oyConfigs_Get(devices, i); device_new = oyConfig_FromRegistration(CMM_BASE_REG, 0); printf(PRFX "Backend core:\n%s", oyOptions_GetText(*oyConfig_GetOptions(device,"backend_core"), oyNAME_NICK)); printf(PRFX "Data:\n%s", oyOptions_GetText(*oyConfig_GetOptions(device,"data"), oyNAME_NICK)); /*Ignore device without a device_name*/ if (!oyOptions_FindString(*oyConfig_GetOptions(device,"backend_core"), "device_name", NULL)) { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n", _DBG_ARGS_, "The \"device_name\" is NULL, or missing from config object!"); oyConfig_Release(&device); oyConfig_Release(&device_new); g_error++; continue; } /*Handle "driver_version" option [OUT] */ if (version_opt) { oyOption_s *tmp = oyOption_Copy(version_opt, 0); oyOptions_MoveIn(*oyConfig_GetOptions(device_new,"backend_core"), &tmp, -1); } /* 1. Get the "device_name" from old device */ name_opt_dev = oyConfig_Find(device, "device_name"); device_name = oyOption_GetValueText(name_opt_dev, allocateFunc); oyOptions_MoveIn(*oyConfig_GetOptions(device_new,"backend_core"), &name_opt_dev, -1); /* 2. Get the "device_context" from old device */ /* It should be there, see "list" call above */ context_opt_dev = oyConfig_Find(device, "device_context"); if (context_opt_dev) { device_context = (SANE_Device*)oyOption_GetData(context_opt_dev, NULL, allocateFunc); if (device_context) { oyOptions_MoveIn(*oyConfig_GetOptions(device_new,"data"), &context_opt_dev, -1); } else { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n", _DBG_ARGS_, "The \"device_context\" is NULL!"); oyOption_Release(&context_opt_dev); g_error++; } } else { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n", _DBG_ARGS_, "The \"device_context\" option is missing!"); g_error++; } /* 3. Get the scanner H/W properties from old device */ /* FIXME: we only recompute them, just in case they are not in old device */ if (device_context) { DeviceInfoFromContext_(device_context, oyConfig_GetOptions(device_new,"backend_core")); } /* 4. Get the "device_handle" from old device */ /* If not there, get one from SANE */ handle_opt_dev = oyConfig_Find(device, "device_handle"); if (handle_opt_dev) { oyPointer_s * oy_struct = (oyPointer_s*)oyOption_GetStruct( handle_opt_dev, oyOBJECT_POINTER_S ); device_handle = (SANE_Handle)oyPointer_GetPointer(oy_struct); oyPointer_Release( &oy_struct ); oyOptions_MoveIn(*oyConfig_GetOptions(device_new,"data"), &handle_opt_dev, -1); } else { printf(PRFX "Opening sane device \"%s\"..", device_name); fflush(NULL); status = sane_open( device_name, &device_handle ); if (status != SANE_STATUS_GOOD) printf("[FAIL: %s]\n", sane_strstatus(status)); else printf("[OK]\n"); } if (handle_opt_dev || status == SANE_STATUS_GOOD) { /* Use the device_handle to get the device color options */ ColorInfoFromHandle(device_handle, oyConfig_GetOptions(device_new,"backend_core")); /*5. Set the rank map*/ oyConfig_SetRankMap( device_new, _api8.rank_map ); } /*Cleanup*/ /* Remove old, add new device */ oyConfig_Release(&device); oyConfigs_ReleaseAt(devices, i); oyConfigs_MoveIn(devices, &device_new, -1); /*If we had to open a SANE device, we'll have to close it*/ if (status == SANE_STATUS_GOOD) { printf(PRFX "sane_close(%s)\n", device_name); sane_close(device_handle); } free(device_context); free(device_name); } } else { /*unsupported, wrong or no command */ SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n " "No supported commands in options:\n%s", _DBG_ARGS_, oyOptions_GetText(options, oyNAME_NICK) ); ConfigsFromPatternUsage((oyStruct_s *) options); g_error = 1; } /*Cleanup*/ if (call_sane_exit) { printf(PRFX "sane_exit()\n"); sane_exit(); } oyOption_Release(&version_opt); printf(PRFX "Leaving %s\n", __func__); return g_error; }
/** Function Configs_FromPattern * @brief CMM_NICK oyCMMapi8_s scanner devices * * @param[in] registration a string to compare ?????? * @param[in] options read what to do from the options object * @param[out] s Return a configuration for each device found * * @version Oyranos: 0.1.10 * @since 2009/01/19 (Oyranos: 0.1.10) * @date 2009/02/09 */ int Configs_FromPattern(const char *registration, oyOptions_s * options, oyConfigs_s ** s) { oyConfig_s *device = NULL; oyConfigs_s *devices = NULL; oyOption_s *context_opt = NULL, *handle_opt = NULL, *version_opt = NULL, *name_opt = NULL; int i, num_devices, g_error = 0, status, call_sane_exit = 0; const char *device_name = 0, *command_list = 0, *command_properties = 0; const SANE_Device **device_list = NULL; int rank; oyAlloc_f allocateFunc = malloc; printf(PRFX "Entering %s(). Options:\n%s", __func__, oyOptions_GetText(options, oyNAME_NICK)); rank = oyFilterRegistrationMatch(_api8.registration, registration, oyOBJECT_CMM_API8_S); command_list = oyOptions_FindString(options, "command", "list"); command_properties = oyOptions_FindString(options, "command", "properties"); device_name = oyOptions_FindString(options, "device_name", 0); /* "error handling" section */ if (rank == 0) { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n " "Registration match Failed. Options:\n%s", _DBG_ARGS_, oyOptions_GetText(options, oyNAME_NICK)); return 1; } if (s == NULL) { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n " "oyConfigs_s is NULL! Options:\n%s", _DBG_ARGS_, oyOptions_GetText(options, oyNAME_NICK)); return 1; } if (*s != NULL) { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n " "Devices struct already present! Options:\n%s", _DBG_ARGS_, oyOptions_GetText(options, oyNAME_NICK)); return 1; } if (!device_name && command_properties) { SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n " "Device_name is mandatory for properties command:\n%s", _DBG_ARGS_, oyOptions_GetText(options, oyNAME_NICK)); return 1; } /* "help" call section */ if (oyOptions_FindString(options, "command", "help") || !options || !oyOptions_Count(options)) { /** oyMSG_WARN should make shure our message is visible. */ ConfigsFromPatternUsage((oyStruct_s *) options); return 0; } context_opt = oyOptions_Find(options, "device_context", oyNAME_PATTERN); handle_opt = oyOptions_Find(options, "device_handle", oyNAME_PATTERN); name_opt = oyOptions_Find(options, "oyNAME_NAME", oyNAME_PATTERN); /*Handle "driver_version" option [IN] */ check_driver_version(options, &version_opt, &call_sane_exit); devices = oyConfigs_New(0); if (command_list) { /* "list" call section */ if (device_name && /*If a user provides a device_name option,*/ !context_opt && /*and does not need the device_context data,*/ !name_opt /*or the oyNAME_NAME description*/ ) num_devices = 1; /*then we can get away without calling GetDevices()*/ else if (GetDevices(&device_list, &num_devices) != 0) { num_devices = 0; /*So that for loop will not run*/ ++g_error; } for (i = 0; i < num_devices; ++i) { int error = 0; const char *sane_name = NULL, *sane_model = NULL; if (device_list) { sane_name = device_list[i]->name; sane_model = device_list[i]->model; } else { sane_name = device_name; } /*Handle "device_name" option [IN] */ if (device_name && /*device_name is provided*/ sane_name && /*and sane_name has been retrieved*/ strcmp(device_name, sane_name) != 0) /*and they don't match,*/ continue; /*then try the next*/ device = oyConfig_FromRegistration(CMM_BASE_REG, 0); /*Handle "driver_version" option [OUT] */ if (version_opt) { oyOption_s * tmp = oyOption_Copy(version_opt, 0); oyOptions_MoveIn(*oyConfig_GetOptions(device,"backend_core"), &tmp, -1); } /*Handle "device_name" option [OUT] */ oyOptions_SetFromString(oyConfig_GetOptions(device,"backend_core"), CMM_BASE_REG OY_SLASH "device_name", sane_name, OY_CREATE_NEW); /*Handle "oyNAME_NAME" option */ if (name_opt) oyOptions_SetFromString(oyConfig_GetOptions(device,"backend_core"), CMM_BASE_REG OY_SLASH "oyNAME_NAME", sane_model, OY_CREATE_NEW); /*Handle "device_context" option */ /* SANE Backend protocol states that device_context is *always* returned * This is a slight variation: Only when GetDevices() is called will it be returned, * unless we call sane_exit*/ if (device_list && !call_sane_exit) { oyBlob_s *context_blob = oyBlob_New(NULL); oyOption_s *context_opt = oyOption_FromRegistration( CMM_BASE_REG OY_SLASH "device_context", 0); oyBlob_SetFromData(context_blob, (oyPointer) device_list[i], sizeof(SANE_Device), "sane"); oyOption_MoveInStruct(context_opt, (oyStruct_s **) & context_blob); oyOptions_MoveIn(*oyConfig_GetOptions(device,"data"), &context_opt, -1); } /*Handle "device_handle" option */ if (handle_opt && !call_sane_exit) { oyPointer_s *handle_ptr = NULL; SANE_Handle h; status = sane_open(sane_name, &h); if (status == SANE_STATUS_GOOD) { handle_ptr = oyPointer_New(0); oyPointer_Set(handle_ptr, "SANE", "handle", (oyPointer)h, "sane_release_handle", sane_release_handle); oyOptions_MoveInStruct(oyConfig_GetOptions(device,"data"), CMM_BASE_REG OY_SLASH "device_handle", (oyStruct_s **) &handle_ptr, OY_CREATE_NEW); } else printf(PRFX "Unable to open sane device \"%s\": %s\n", sane_name, sane_strstatus(status)); } oyConfig_SetRankMap( device, _api8.rank_map ); error = oyConfigs_MoveIn(devices, &device, -1); /*Cleanup*/ if (error) { oyConfig_Release(&device); ++g_error; } } *s = devices; } else if (command_properties) { /* "properties" call section */ const SANE_Device *device_context = NULL; SANE_Device *aux_context = NULL; SANE_Handle device_handle = NULL; /*Return a full list of scanner H/W & * SANE driver S/W color options * with the according rank map */ device = oyConfig_FromRegistration(CMM_BASE_REG, 0); /*Handle "driver_version" option [OUT] */ if (version_opt) { oyOption_s *tmp = oyOption_Copy(version_opt, 0); oyOptions_MoveIn(*oyConfig_GetOptions(device,"backend_core"), &tmp, -1); } /*1a. Get the "device_context"*/ if (!context_opt) { /*we'll have to get it ourselves*/ if (GetDevices(&device_list, &num_devices) == 0) { device_context = *device_list; while (device_context) { if(device_name && device_context->name && strcmp(device_name,device_context->name) == 0) break; device_context++; } if (!device_context) { printf(PRFX "device_name does not match any installed device.\n"); g_error++; } } else { g_error++; } } else { aux_context = (SANE_Device*)oyOption_GetData(context_opt, NULL, allocateFunc); device_context = aux_context; } /*1b. Use the "device_context"*/ if (device_context) DeviceInfoFromContext_(device_context, oyConfig_GetOptions(device,"backend_core")); /*2a. Get the "device_handle"*/ if (!handle_opt) { status = sane_open( device_name, &device_handle ); if (status != SANE_STATUS_GOOD) { printf(PRFX "Unable to open sane device \"%s\": %s\n", device_name, sane_strstatus(status)); g_error++; } } else { oyPointer_s * oy_struct = (oyPointer_s*) oyOption_GetStruct( handle_opt, oyOBJECT_POINTER_S ); device_handle = (SANE_Handle)oyPointer_GetPointer(oy_struct); oyPointer_Release( &oy_struct ); } if (device_handle) { /*2b. Use the "device_handle"*/ ColorInfoFromHandle(device_handle, oyConfig_GetOptions(device,"backend_core")); /*3. Set the rank map*/ oyConfig_SetRankMap( device, _api8.rank_map ); } oyConfigs_MoveIn(devices, &device, -1); /*Cleanup*/ free(aux_context); *s = devices; } else { /*unsupported, wrong or no command */ SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n " "No supported commands in options:\n%s", _DBG_ARGS_, oyOptions_GetText(options, oyNAME_NICK) ); ConfigsFromPatternUsage((oyStruct_s *) options); g_error = 1; } /*Global Cleanup*/ if (call_sane_exit) { printf(PRFX "sane_exit()\n"); sane_exit(); } oyOption_Release(&context_opt); oyOption_Release(&handle_opt); oyOption_Release(&version_opt); oyOption_Release(&name_opt ); printf(PRFX "Leaving %s\n", __func__); return g_error; }
/** Function oyFilterNode_SetContext_ * @memberof oyFilterNode_s * @brief Set module context in a filter * @internal * * The api4 data is passed to a interpolator specific transformer. The result * of this transformer will on request be cached by Oyranos as well. * * @param[in] node filter * @param[in,out] blob context to fill; expensive * @return error * * @version Oyranos: 0.9.6 * @date 2014/06/26 * @since 2008/11/02 (Oyranos: 0.1.8) */ int oyFilterNode_SetContext_( oyFilterNode_s_ * node, oyBlob_s_ * blob ) { int error = 0; oyFilterCore_s_ * core_ = node->core; if(error <= 0) { size_t size = 0; oyHash_s * hash4 = 0, /* public context provider */ * hash7 = 0; /* data processor part */ oyPointer ptr = 0; oyPointer_s * cmm_ptr4 = 0, * cmm_ptr7 = 0; /* Cache Search * 1. hash from input * 2. query for hash in cache * 3. check * 3a. eighter take cache entry * 3b. or ask CMM * 3b.1. update cache entry */ if(oy_debug && getenv("OY_DEBUG_WRITE")) { size = 0; ptr = oyFilterNode_TextToInfo_( node, &size, oyAllocateFunc_ ); if(ptr) oyWriteMemToFile_( "test_dbg_color.icc", ptr, size ); } /* 1. + 2. query in cache for api7 */ hash7 = oyFilterNode_GetHash_(node, 7); if(error <= 0) { /* select the module by option */ oyOption_s * ct = oyOptions_Find( node->core->options_, "////context", oyNAME_PATTERN ); const char * pattern = oyOption_GetValueString( ct, 0 ); if(pattern && !oyFilterRegistrationMatch( core_->registration_, pattern, 0 )) { oyMessageFunc_p( oyMSG_DBG, (oyStruct_s*) node, OY_DBG_FORMAT_ "create core from pattern: %s", OY_DBG_ARGS_, oyFilterNode_GetText( (oyFilterNode_s*)node,oyNAME_NICK) ); error = oyFilterNode_SetFromPattern_( node, 1, pattern ); if(error) { if(oyOption_GetFlags( ct ) & oyOPTIONATTRIBUTE_EDIT) { oyMessageFunc_p( oyMSG_WARN, (oyStruct_s*) node, OY_DBG_FORMAT_ "edited pattern not available: %d %s", OY_DBG_ARGS_, oyObject_GetId(ct->oy_), pattern ); error = 1; goto clean; } else error = 0; } else core_ = node->core; oyHash_Release( &hash7 ); hash7 = oyFilterNode_GetHash_(node, 7); } oyOption_Release( &ct ); ct = oyOptions_Find( node->core->options_, "////renderer", oyNAME_PATTERN ); pattern = oyOption_GetValueString( ct, 0 ); if(pattern && !oyFilterRegistrationMatch( node->api7_->registration, pattern, 0 )) { oyMessageFunc_p( oyMSG_DBG, (oyStruct_s*) node, OY_DBG_FORMAT_ "create node from pattern: %s", OY_DBG_ARGS_, oyFilterNode_GetText( (oyFilterNode_s*)node,oyNAME_NICK) ); error = oyFilterNode_SetFromPattern_( node, 0, pattern ); if(error) { if(oyOption_GetFlags( ct ) & oyOPTIONATTRIBUTE_EDIT) { error = 1; goto clean; } else error = 0; } else core_ = node->core; oyHash_Release( &hash7 ); hash7 = oyFilterNode_GetHash_(node, 7); } /* 3. check and 3.a take*/ cmm_ptr7 = (oyPointer_s*) oyHash_GetPointer( hash7, oyOBJECT_POINTER_S); if(!(cmm_ptr7 && oyPointer_GetPointer(cmm_ptr7)) || blob) { /* write the cmm4 context to memory */ if(blob) { if(oy_debug) error = oyOptions_SetFromString( &node->tags, "////verbose", "true", OY_CREATE_NEW ); /* oy_debug is used to obtain a complete data set */ ptr = oyFilterNode_ContextToMem_( node, &size, oyAllocateFunc_); oyBlob_SetFromData( (oyBlob_s*)blob, ptr, size, core_->api4_->context_type ); if(oy_debug) error = oyOptions_SetFromString( &node->tags, "////verbose", "false", 0 ); goto clean; } /* 2. query in cache for api4 */ hash4 = oyFilterNode_GetHash_(node, 4); cmm_ptr4 = (oyPointer_s*) oyHash_GetPointer( hash4, oyOBJECT_POINTER_S); if(!cmm_ptr4) { cmm_ptr4 = oyPointer_New(0); } if(!oyPointer_GetPointer(cmm_ptr4)) { size = 0; /* 3b. ask CMM */ ptr = oyFilterNode_ContextToMem_( node, &size, oyAllocateFunc_); if(!ptr || !size) { oyOption_s * ct = oyOptions_Find( core_->options_, "////context", oyNAME_PATTERN ); oyMessageFunc_p( oyMSG_DBG, (oyStruct_s*) node, OY_DBG_FORMAT_ "device link creation failed", OY_DBG_ARGS_); if(!(oyOption_GetFlags( ct ) & oyOPTIONATTRIBUTE_EDIT)) { char * pattern = oyFilterNode_GetFallback_( node, 1 ); oyMessageFunc_p( oyMSG_WARN, (oyStruct_s*) node, OY_DBG_FORMAT_ "create core from fallback: %s", OY_DBG_ARGS_, pattern ); error = oyFilterNode_SetFromPattern_( node, 1, pattern ); if(error) { error = 1; oyMessageFunc_p( oyMSG_ERROR, (oyStruct_s*) node, OY_DBG_FORMAT_ "no device link for caching\n%s", OY_DBG_ARGS_, oyFilterNode_GetText( (oyFilterNode_s*)node,oyNAME_NICK)); goto clean; } else core_ = node->core; ptr = oyFilterNode_ContextToMem_( node, &size, oyAllocateFunc_ ); oyFree_m_( pattern ); } if(!ptr || !size) { oyMessageFunc_p( oyMSG_ERROR, (oyStruct_s*) node, OY_DBG_FORMAT_ "no device link for caching\n%s", OY_DBG_ARGS_, oyFilterNode_GetText( (oyFilterNode_s*)node,oyNAME_NICK)); error = 1; oyPointer_Release( &cmm_ptr4 ); } else if(oy_debug) oyMessageFunc_p( oyMSG_WARN, (oyStruct_s*) node, OY_DBG_FORMAT_ "use fallback CMM\n%s", OY_DBG_ARGS_, oyFilterNode_GetText( (oyFilterNode_s*)node, oyNAME_NICK )); } if(!error) { /* 3b.1. update the hash as the CMM can change options */ hash4 = oyFilterNode_GetHash_( node, 4 ); oyPointer_Release( &cmm_ptr4 ); cmm_ptr4 = (oyPointer_s*) oyHash_GetPointer( hash4, oyOBJECT_POINTER_S); hash7 = oyFilterNode_GetHash_( node, 7 ); if(!cmm_ptr4) cmm_ptr4 = oyPointer_New(0); error = oyPointer_Set( cmm_ptr4, core_->api4_->id_, core_->api4_->context_type, ptr, "oyPointerRelease", oyPointerRelease); oyPointer_SetSize( cmm_ptr4, size ); /* 3b.2. update cmm4 cache entry */ error = oyHash_SetPointer( hash4, (oyStruct_s*) cmm_ptr4); } } if(error <= 0 && cmm_ptr4 && oyPointer_GetPointer(cmm_ptr4)) { if(node->backend_data && node->backend_data->release) node->backend_data->release( (oyStruct_s**)&node->backend_data); if( oyStrcmp_( node->api7_->context_type, core_->api4_->context_type ) != 0 ) { cmm_ptr7 = oyPointer_New(0); error = oyPointer_Set( cmm_ptr7, node->api7_->id_, node->api7_->context_type, 0, 0, 0); /* 3b.3. search for a convertor and convert */ oyPointer_ConvertData( cmm_ptr4, cmm_ptr7, (oyFilterNode_s*)node ); node->backend_data = cmm_ptr7; /* 3b.4. update cmm7 cache entry */ error = oyHash_SetPointer( hash7, (oyStruct_s*) cmm_ptr7); } else node->backend_data = oyPointer_Copy( cmm_ptr4, 0 ); } if(oy_debug && getenv("OY_DEBUG_WRITE")) { int id = oyFilterNode_GetId( (oyFilterNode_s*)node ); char * file_name = 0; oyAllocHelper_m_( file_name, char, 80, 0, return 1 ); sprintf( file_name, "dbg_color_dl-node[%d].icc", id ); if(ptr && size && node->backend_data) oyWriteMemToFile_( file_name, ptr, size ); oyFree_m_(file_name); } } else