/** Function oyConversion_Release__Members * @memberof oyConversion_s * @brief Custom Conversion destructor * @internal * * This function will free up all memmory allocated by the * input object. First all object members witch have their * own release method are deallocated. Then the deallocateFunc_ * of the oy_ object is used to release the rest of the members * that were allocated with oy_->allocateFunc_. * * @param[in] conversion the Conversion object * * @version Oyranos: x.x.x * @since YYYY/MM/DD (Oyranos: x.x.x) * @date YYYY/MM/DD */ void oyConversion_Release__Members( oyConversion_s_ * conversion ) { /* Deallocate members here * E.g: oyXXX_Release( &conversion->member ); */ oyFilterGraph_s * g = oyFilterGraph_New( 0 ); int i,n; oyFilterGraph_SetFromNode( g, (oyFilterNode_s*)conversion->input, 0, 0 ); oyFilterNode_Release( (oyFilterNode_s**)&conversion->input ); oyFilterNode_Release( (oyFilterNode_s**)&conversion->out_ ); n = oyFilterGraph_CountNodes( g, "", NULL ); for(i = 0; i < n; ++i) { oyFilterNode_s * node = oyFilterGraph_GetNode( g, i, "", NULL ), * temp; int ref = oyObject_GetRefCount( node->oy_ ); if(ref > 1) { temp = node; oyFilterNode_Release( &temp ); } oyFilterNode_Release( &node ); } oyFilterGraph_Release( &g ); conversion->input = NULL; conversion->out_ = NULL; if(conversion->oy_->deallocateFunc_) { #if 0 oyDeAlloc_f deallocateFunc = conversion->oy_->deallocateFunc_; #endif /* Deallocate members of basic type here * E.g.: deallocateFunc( conversion->member ); */ } }
uint16_t * oyProfileGetWhitePointRamp( int width, oyProfile_s * p, oyOptions_s * options ) { uint16_t * ramp = calloc( sizeof(uint16_t), width*3); oyImage_s * input = oyImage_Create( width, 1, ramp, OY_TYPE_123_16, p, 0 ); oyImage_s * output = oyImage_Create( width, 1, ramp, OY_TYPE_123_16, p, 0 ); int i,j, error, mul = 65536/width; oyConversion_s * cc = oyConversion_CreateBasicPixels( input, output, options, NULL); for(i = 0; i < width; ++i) { for(j = 0; j < 3; ++j) ramp[i*3 + j] = i * mul; } if(getenv("OY_DEBUG_WRITE")) oyImage_WritePPM( input, "wtpt-effect-raw.ppm", "unaltered gray ramp" ); oyConversion_Correct( cc, "//" OY_TYPE_STD "/icc_color", 0, NULL); error = oyConversion_RunPixels( cc, 0 ); if(error) oyMessageFunc_p( oyMSG_WARN,(oyStruct_s*)p, OY_DBG_FORMAT_ "found issue while converting ramp: %d", OY_DBG_ARGS_, error ); if(getenv("OY_DEBUG_WRITE")) { oyFilterGraph_s * cc_graph = oyConversion_GetGraph( cc ); oyFilterNode_s * icc = oyFilterGraph_GetNode( cc_graph, -1, "///icc_color", 0 ); char * comment = oyjlStringCopy("gray ramp", oyAllocateFunc_); const char * ndesc = oyFilterNode_GetText( icc, oyNAME_NAME ); oyjlStringAdd( &comment, oyAllocateFunc_, oyDeAllocateFunc_, "\n%s", ndesc ); oyImage_WritePPM( input, "wtpt-effect-gray.ppm", comment ); oyFree_m_(comment); oyFilterGraph_Release( &cc_graph ); oyFilterNode_Release( &icc ); } oyImage_Release( &input ); oyImage_Release( &output ); return ramp; }
/** Function oyFilterNode_Create * @memberof oyFilterNode_s * @brief Initialise a new filter node object properly * * @param registration the processing filter @ref registration string * @param filter the context filter * @param object the optional object * * @version Oyranos: 0.9.6 * @date 2014/07/01 * @since 2008/07/30 (Oyranos: 0.1.8) */ oyFilterNode_s * oyFilterNode_Create(const char * registration, oyFilterCore_s * filter, oyObject_s object ) { oyFilterNode_s_ * s = 0; int error = 0; oyAlloc_f allocateFunc_ = 0; oyFilterCore_s_ * filter_ = (oyFilterCore_s_*)filter; if(!filter) return (oyFilterNode_s*) s; s = (oyFilterNode_s_*) oyFilterNode_New( object ); error = !s; if(error <= 0) { allocateFunc_ = s->oy_->allocateFunc_; s->core = (oyFilterCore_s_*)oyFilterCore_Copy( filter, object ); if(!s->core) { WARNc2_S("Could not copy filter: %s %s", filter_->registration_, filter_->category_) error = 1; } if(error <= 0) s->api7_ = (oyCMMapi7_s_*) oyCMMsGetFilterApi_( registration, oyOBJECT_CMM_API7_S ); if(error <= 0 && !s->api7_) { WARNc2_S("Could not obtain filter api7 for: %s %s", filter_->registration_, filter_->category_) error = 1; } if(s->api7_) { s->plugs_n_ = s->api7_->plugs_n + s->api7_->plugs_last_add; if(s->api7_->plugs_last_add) --s->plugs_n_; s->sockets_n_ = s->api7_->sockets_n + s->api7_->sockets_last_add; if(s->api7_->sockets_last_add) --s->sockets_n_; } if(s->core) { int count = oyFilterNode_EdgeCount( (oyFilterNode_s*) s, 0, 0 ); size_t len; if(count < 0) count = 0; len = sizeof(oyFilterSocket_s*) * (count + 1); s->sockets = allocateFunc_( len ); memset( s->sockets, 0, len ); len = sizeof(oyFilterSocket_s*) * (oyFilterNode_EdgeCount( (oyFilterNode_s*) s, 1, 0 ) + 1); len = len?len:sizeof(oyFilterSocket_s*); s->plugs = allocateFunc_( len ); memset( s->plugs, 0, len ); s->relatives_ = allocateFunc_( oyStrlen_(filter_->category_) + 24 ); oySprintf_( s->relatives_, "%d: %s", oyObject_GetId(s->oy_), s->core->category_); } } if(error) oyFilterNode_Release( (oyFilterNode_s**) &s ); return (oyFilterNode_s*) s; }
/** Function oyFilterNode_Connect * @memberof oyFilterNode_s * @brief Connect two nodes by a edge * * @param input the node to provide a socket * @param socket_nick name of socket * @param output the node providing a plug * @param plug_nick name of plug * @param flags unused * @return error * * @version Oyranos: 0.1.10 * @since 2009/02/26 (Oyranos: 0.1.10) * @date 2009/02/26 */ int oyFilterNode_Connect ( oyFilterNode_s * input, const char * socket_nick, oyFilterNode_s * output, const char * plug_nick, int flags OY_UNUSED ) { oyFilterNode_s_ * s = (oyFilterNode_s_*)input; int error = !s; oyFilterPlug_s * out_plug = 0; oyFilterSocket_s * output_socket = 0, * in_socket = 0; int pos, out_pos; oyCheckType__m( oyOBJECT_FILTER_NODE_S, return 1 ) s = (oyFilterNode_s_*)output; oyCheckType__m( oyOBJECT_FILTER_NODE_S, return 1 ) if(error <= 0) { if(error <= 0 && (!s->core || !s->core->api4_)) { WARNcc2_S( s, "%s: %s", _("attempt to add a incomplete filter"), s->relatives_ ); error = 1; } if(error <= 0 && !oyFilterNode_EdgeCount( input, 0, OY_FILTEREDGE_FREE )) { WARNcc2_S( input, "%s: %s", "input node has no free socket", oyFilterCore_GetName( (oyFilterCore_s*)oyFilterNodePriv_m(input)->core, oyNAME_NAME) ); error = 1; } if(error <= 0) { if(socket_nick) pos = oyFilterNode_GetConnectorPos( input, 0, socket_nick, 0, 0 ); else pos = 0; if(pos >= 0) in_socket = oyFilterNode_GetSocket( input, pos ); if(plug_nick) out_pos = oyFilterNode_GetConnectorPos( output, 1, plug_nick, 0, OY_FILTEREDGE_FREE ); else out_pos = 0; if(out_pos >= 0) out_plug = oyFilterNode_GetPlug( output, out_pos ); if(!out_plug) { WARNcc3_S( output, "\n %s: \"%s\" %s", "Could not find plug for filter", oyFilterCore_GetName( (oyFilterCore_s*)oyFilterNodePriv_m(output)->core, oyNAME_NAME), socket_nick ); error = 1; } if(error <= 0) { if(oyFilterNode_ConnectorMatch( input, pos, out_plug )) output_socket = oyFilterNode_GetSocket( output, 0 ); else { WARNcc3_S( input, "\n %s: %s -> %s", "Filter connectors do not match", oyFilterNodePriv_m(input)->relatives_, oyFilterNodePriv_m(output)->relatives_ ); error = 1; } } if(error <= 0 && output_socket && !oyFilterSocketPriv_m(output_socket)->data && in_socket && oyFilterSocketPriv_m(in_socket)->data) { oyFilterSocketPriv_m(output_socket)->data = oyFilterSocketPriv_m(in_socket)->data->copy( oyFilterSocketPriv_m(in_socket)->data, 0 ); if(oy_debug_objects >= 0) oyObjectDebugMessage_( oyFilterSocketPriv_m(output_socket)->data->oy_, __func__, oyStructTypeToText(oyFilterSocketPriv_m(output_socket)->data->type_) ); } if(error <= 0) { oyFilterPlug_s_ * out_plug_ = (oyFilterPlug_s_*) out_plug; oyFilterSocket_s_* in_socket_ = (oyFilterSocket_s_*)in_socket; error = oyFilterPlug_ConnectIntoSocket( &out_plug, &in_socket ); if(error <= 0) { oyFilterNode_Release( (oyFilterNode_s**) &out_plug_->node ); out_plug_->node = (oyFilterNode_s_*) oyFilterNode_Copy( output, NULL ); oyFilterNode_Release( (oyFilterNode_s**) &in_socket_->node ); in_socket_->node = (oyFilterNode_s_*) oyFilterNode_Copy( input, NULL ); } } } else WARNcc2_S( input, "%s: %d", _("?? Nothing to add ??"), oyObject_GetId(input->oy_)); } oyFilterSocket_Release( &output_socket ); return error; }
/** Function oyDrawScreenImage * @brief generate a Oyranos image from a given context for display * * The function asks the 'oydi' node to provide parameters to render a * oyImage_s from a prepared oyConversion_s context. * * @param[in] context the Oyranos graph * @param[in,out] ticket rendering context for tracking * rectangles * @param[in] display_rectangle absolute coordinates of visible image * in relation to display * @param[in,out] old_display_rectangle * rembering of display_rectangle + @param[in,out] old_roi_rectangle remembering of ticket's ROI (optional) * @param[in] system_type the system dependent type specification * - "X11" is well supported * - "oy-test" for internal tests * @param[in] data_type_request oyUINT8 or oyUINT16 * @param[in] display the system display with system_type: * - "X11": a Display object * @param[in] window the system window with system_type: * - "X11": a Window ID * @param[in] dirty explicite redraw * @param[out] image the image from graph to display * @return 0 - success, -1 - issue, >= 1 - error * * @version Oyranos: 0.9.6 * @date 2016/09/22 * @since 2010/09/05 (Oyranos: 0.1.11) */ int oyDrawScreenImage ( oyConversion_s * context, oyPixelAccess_s * ticket, oyRectangle_s * display_rectangle, oyRectangle_s * old_display_rectangle, oyRectangle_s * old_roi_rectangle, const char * system_type, oyDATATYPE_e data_type_request, void * display, void * window, int dirty, oyImage_s * image ) { int result = 0; if(context) { double X,Y,W,H; int channels = 0; oyFilterNode_s * node_out = 0; oyRectangle_s * disp_rectangle = 0, * ticket_roi = 0; oyOptions_s * image_tags = 0; oyDATATYPE_e data_type = oyUINT8; oyPixel_t pt = 0; oyRectangle_GetGeo( display_rectangle, &X, &Y, &W, &H ); if(!image) return 1; if( W <= 0 || H <= 0) return -1; image_tags = oyImage_GetTags( image ); if(window && strcmp("X11", system_type) == 0) { #if defined(XCM_HAVE_X11) /* add X11 window and display identifiers to output image */ oyOption_s * o = 0; Display *disp = (Display*) display; Window w = (Window) window; int count = oyOptions_CountType( image_tags, "//" OY_TYPE_STD "/display/window_id", oyOBJECT_BLOB_S ); if(!count && w) { oyBlob_s * win_id = oyBlob_New(0), * display_id = oyBlob_New(0); if(win_id) { oyBlob_SetFromStatic( win_id, (oyPointer)w, 0, 0 ); o = oyOption_FromRegistration( "//" OY_TYPE_STD "/display/window_id", 0 ); oyOption_MoveInStruct( o, (oyStruct_s**)&win_id ); oyOptions_MoveIn( image_tags, &o, -1 ); oyBlob_SetFromStatic( display_id, (oyPointer)disp, 0, 0 ); o = oyOption_FromRegistration( "//" OY_TYPE_STD "/display/display_id", 0 ); oyOption_MoveInStruct( o, (oyStruct_s**)&display_id ); oyOptions_MoveIn( image_tags, &o, -1 ); oyOptions_SetFromText( &image_tags, "//" OY_TYPE_STD "/display/display_name", DisplayString(disp), OY_CREATE_NEW ); } else printf("%s:%d WARNING: no X11 Window obtained or\n" " no oyBlob_s allocateable\n", __FILE__,__LINE__); } #endif } else if(strcmp("oy-test", system_type) == 0) oyOptions_SetFromText( &image_tags, "//" OY_TYPE_STD "/display/display_name", system_type, OY_CREATE_NEW ); /* check if the actual data can be displayed */ pt = oyImage_GetPixelLayout( image, oyLAYOUT ); data_type = oyToDataType_m( pt ); channels = oyToChannels_m( pt ); if(pt != 0 && ((channels != 4 && channels != 3) || data_type != data_type_request)) { printf( "%s:%d WARNING: wrong image data format: %s\n%s\n" "need 4 or 3 channels with %s\n", __FILE__,__LINE__, oyOptions_FindString( image_tags, "filename", 0 ), image ? oyObject_GetName( image->oy_, oyNAME_NICK ) : "", oyDataTypeToText( data_type_request ) ); return 1; } /* Inform about the images display coverage. */ disp_rectangle = (oyRectangle_s*) oyOptions_GetType( image_tags, -1, "display_rectangle", oyOBJECT_RECTANGLE_S ); oyRectangle_SetGeo( disp_rectangle, X,Y,W,H ); node_out = oyConversion_GetNode( context, OY_OUTPUT ); ticket_roi = oyPixelAccess_GetArrayROI( ticket ); /* decide wether to refresh the cached rectangle of our static image */ if( node_out && /* Did the window area move? */ ((!oyRectangle_IsEqual( disp_rectangle, old_display_rectangle ) || /* Something explicite to update? */ (old_roi_rectangle && !oyRectangle_IsEqual( ticket_roi, old_roi_rectangle ))|| /* Did the image move? */ oyPixelAccess_GetStart( ticket,0 ) != oyPixelAccess_GetOldStart( ticket,0 ) || oyPixelAccess_GetStart( ticket,1 ) != oyPixelAccess_GetOldStart( ticket,1 )) || dirty > 0)) { #ifdef DEBUG_ printf( "%s:%d new display rectangle: %s +%d+%d\n", __FILE__,__LINE__, oyRectangle_Show(disp_rectangle), X, Y ), #endif /* convert the image data */ oyConversion_RunPixels( context, ticket ); if(oy_debug && getenv("OY_DEBUG_WRITE")) { oyImage_s * out = oyConversion_GetImage( context, OY_OUTPUT ); oyImage_WritePPM( out, "debug_image_out.ppm", "image_display output image"); oyImage_Release( &out ); } /* remember the old rectangle */ oyRectangle_SetByRectangle( old_display_rectangle, disp_rectangle ); oyRectangle_SetByRectangle( old_roi_rectangle, ticket_roi ); oyPixelAccess_SetOldStart(ticket,0, oyPixelAccess_GetStart(ticket,0)); oyPixelAccess_SetOldStart(ticket,1, oyPixelAccess_GetStart(ticket,1)); } else result = -1; oyFilterNode_Release( &node_out ); oyOptions_Release( &image_tags ); oyRectangle_Release( &disp_rectangle ); oyRectangle_Release( &ticket_roi ); } if(oy_debug >= 4) fprintf( stderr, "%s:%d %s() result: %d\n", strrchr(__FILE__,'/'),__LINE__,__func__, result ); return result; }
/** @brief implement oyCMMFilter_GetNext_f() * * @version Oyranos: 0.9.6 * @date 2016/04/04 * @since 2013/06/10 (Oyranos: 0.9.5) */ int oyraFilter_ImageExposeRun ( oyFilterPlug_s * requestor_plug, oyPixelAccess_s * ticket ) { int result = 0, error = 0; oyFilterSocket_s * socket = 0; oyFilterNode_s * input_node = 0, * node = 0; oyFilterPlug_s * plug = 0; oyImage_s * image = 0; int dirty = 0; socket = oyFilterPlug_GetSocket( requestor_plug ); node = oyFilterSocket_GetNode( socket ); image = (oyImage_s*)oyFilterSocket_GetData( socket ); if(!image) { result = 1; goto clean_expose1; } if(oy_debug) oyra_msg( oyMSG_WARN, (oyStruct_s*)ticket, OY_DBG_FORMAT_ "image [%d](%d)\n",OY_DBG_ARGS_,oyStruct_GetId((oyStruct_s*)image),oyImage_GetWidth(image) ); { oyRectangle_s * ticket_roi = oyPixelAccess_GetArrayROI( ticket ); double expose = 1.0; oyOptions_s * node_opts = oyFilterNode_GetOptions( node, 0 ); if(!node_opts) dirty = 1; if(dirty) { result = dirty; goto clean_expose2; } plug = oyFilterNode_GetPlug( node, 0 ); /* select node */ input_node = oyFilterNode_GetPlugNode( node, 0 ); /* find filters own expose factor */ error = oyOptions_FindDouble( node_opts, "//" OY_TYPE_STD "/expose/expose", 0, &expose ); if(error) WARNc2_S("%s %d", _("found issues"),error); if(oy_debug > 2) oyra_msg( oyMSG_WARN, (oyStruct_s*)ticket, OY_DBG_FORMAT_ "%s expose: %f",OY_DBG_ARGS_, oyPixelAccess_Show(ticket), expose); if(expose != 1.0) { oyImage_s * output_image = oyPixelAccess_GetOutputImage( ticket ); oyArray2d_s * array_out = oyPixelAccess_GetArray( ticket ); oyProfile_s * p = oyImage_GetProfile( output_image ); icColorSpaceSignature sig = oyProfile_GetSignature( p, oySIGNATURE_COLOR_SPACE ); int layout_dst = oyImage_GetPixelLayout( output_image, oyLAYOUT ); int channels_dst = oyToChannels_m( layout_dst ); int byte_swap = oyToByteswap_m( layout_dst ); int ticket_array_pix_width; /* avoid division by zero */ if(!channels_dst) channels_dst = 1; ticket_array_pix_width = oyArray2d_GetWidth( array_out ) / channels_dst; { int w,h,x,y, i, start_x,start_y; unsigned int max = 1; oyRectangle_s * ticket_roi = oyPixelAccess_GetArrayROI( ticket ); oyRectangle_s_ roi_= {oyOBJECT_RECTANGLE_S,0,0,0, 0,0,0,0}; oyRectangle_s * roi = (oyRectangle_s*)&roi_; uint8_t ** array_out_data; /* get pixel layout infos for copying */ oyDATATYPE_e data_type_out = oyToDataType_m( layout_dst ); int bps_out = oyDataTypeGetSize( data_type_out ); /* get the source pixels */ result = oyFilterNode_Run( input_node, plug, ticket ); /* get the channel buffers */ array_out_data = oyArray2d_GetData( array_out ); w = oyArray2d_GetWidth( array_out ) / channels_dst; h = oyArray2d_GetHeight( array_out ); oyRectangle_SetByRectangle( roi, ticket_roi ); oyRectangle_Scale( roi, ticket_array_pix_width ); start_x = OY_ROUND(roi_.x); start_y = OY_ROUND(roi_.y); switch(data_type_out) { case oyUINT8: max = 255; break; case oyUINT16: max = 65535; break; case oyUINT32: max = UINT32_MAX; break; default: break; } /* expose the samples */ #if defined(USE_OPENMP) #pragma omp parallel for private(x,y,i) #endif for(y = start_y; y < h; ++y) { for(x = start_x; x < w; ++x) { if( (sig == icSigRgbData || sig == icSigXYZData || sig == icSigLabData || sig == icSigYCbCrData) && channels_dst >= 3) { double rgb[3], v; for(i = 0; i < 3; ++i) { switch(data_type_out) { case oyUINT8: rgb[i] = array_out_data[y][x*channels_dst*bps_out + i*bps_out]; break; case oyUINT16: { uint16_t v = *((uint16_t*)&array_out_data[y][x*channels_dst*bps_out + i*bps_out]); if(byte_swap) v = oyByteSwapUInt16(v); rgb[i] = v; } break; case oyUINT32: { uint32_t v = *((uint32_t*)&array_out_data[y][x*channels_dst*bps_out + i*bps_out]); if(byte_swap) v = oyByteSwapUInt32(v); rgb[i] = v; } break; case oyHALF: v = *((uint16_t*)&array_out_data[y][x*channels_dst*bps_out + i*bps_out]); rgb[i] = v; break; case oyFLOAT: v = *((float*)&array_out_data[y][x*channels_dst*bps_out + i*bps_out]); rgb[i] = v; break; case oyDOUBLE: v = *((double*)&array_out_data[y][x*channels_dst*bps_out + i*bps_out]); rgb[i] = v; break; } } oySensibleClip ( rgb, sig, max, expose ); for(i = 0; i < 3; ++i) { v = rgb[i]; switch(data_type_out) { case oyUINT8: array_out_data[y][x*channels_dst*bps_out + i*bps_out] = v; break; case oyUINT16: { uint16_t u16 = v; *((uint16_t*)&array_out_data[y][x*channels_dst*bps_out + i*bps_out]) = byte_swap ? oyByteSwapUInt16(u16) : u16; } break; case oyUINT32: { uint32_t u32 = v; *((uint32_t*)&array_out_data[y][x*channels_dst*bps_out + i*bps_out]) = byte_swap ? oyByteSwapUInt16(u32) : u32; } break; case oyHALF: *((uint16_t*)&array_out_data[y][x*channels_dst*bps_out + i*bps_out]) = v; break; case oyFLOAT: *((float*)&array_out_data[y][x*channels_dst*bps_out + i*bps_out]) = v; break; case oyDOUBLE: *((double*)&array_out_data[y][x*channels_dst*bps_out + i*bps_out]) = v; break; } } } else for(i = 0; i < channels_dst; ++i) { int v; switch(data_type_out) { case oyUINT8: v = array_out_data[y][x*channels_dst*bps_out + i*bps_out] * expose; if(v > 255) v = 255; array_out_data[y][x*channels_dst*bps_out + i*bps_out] = v; break; case oyUINT16: v = *((uint16_t*)&array_out_data[y][x*channels_dst*bps_out + i*bps_out]); if(byte_swap) v = oyByteSwapUInt16(v); v *= expose; if(v > 65535) v = 65535; *((uint16_t*)&array_out_data[y][x*channels_dst*bps_out + i*bps_out]) = byte_swap ? oyByteSwapUInt16(v) : v; break; case oyUINT32: *((uint32_t*)&array_out_data[y][x*channels_dst*bps_out + i*bps_out]) *= expose; break; case oyHALF: *((uint16_t*)&array_out_data[y][x*channels_dst*bps_out + i*bps_out]) *= expose; break; case oyFLOAT: *((float*)&array_out_data[y][x*channels_dst*bps_out + i*bps_out]) *= expose; break; case oyDOUBLE: *((double*)&array_out_data[y][x*channels_dst*bps_out + i*bps_out]) *= expose; break; } } } } } oyArray2d_Release( &array_out ); oyImage_Release( &output_image ); oyProfile_Release( &p ); } else /* expose == 1.0 */ { result = oyFilterNode_Run( input_node, plug, ticket ); } clean_expose2: oyOptions_Release( &node_opts ); oyFilterPlug_Release( &plug ); oyRectangle_Release( &ticket_roi ); oyFilterNode_Release( &input_node ); } clean_expose1: oyImage_Release( &image ); oyFilterSocket_Release( &socket ); oyFilterNode_Release( &node ); return result; }
void ColorContext::setupColorLookupTable(bool advanced) { kDebug() << m_outputName; oyProfile_s *dummyProfile = 0; oyOptions_s *options = 0; if (!m_dstProfile) m_dstProfile = dummyProfile = oyProfile_FromStd(oyASSUMED_WEB, icc_profile_flags, 0); /* skip dummyProfile to dummyProfile conversion */ if (!m_srcProfile && dummyProfile) { if (dummyProfile) oyProfile_Release(&dummyProfile); return; } if (!m_srcProfile) { m_srcProfile = oyProfile_FromStd(oyASSUMED_WEB, icc_profile_flags, 0); if (!m_srcProfile) { kError() << "Output" << m_outputName << ":" << "no assumed dummyProfile source profile"; kWarning() << "Output" << m_outputName << "using dummy clut"; buildDummyClut(m_clut); return; } } int error = 0; int flags = 0; // Optionally set advanced options from Oyranos if (advanced) flags = oyOPTIONATTRIBUTE_ADVANCED; // Allocate memory for clut data m_clut.resize(CLUT_ELEMENT_COUNT); kDebug() << "Color conversion for" << m_outputName << "flags" << flags << (advanced ? "advanced" : ""); oyImage_s *imageIn = oyImage_Create( LUT_GRID_POINTS, LUT_GRID_POINTS * LUT_GRID_POINTS, m_clut.data(), OY_TYPE_123_16, m_srcProfile, 0); oyImage_s *imageOut = oyImage_Create( LUT_GRID_POINTS, LUT_GRID_POINTS * LUT_GRID_POINTS, m_clut.data(), OY_TYPE_123_16, m_dstProfile, 0); oyConversion_s *conversion = oyConversion_CreateBasicPixels(imageIn, imageOut, options, 0); if (!conversion) { kWarning() << "No conversion created for" << m_outputName; if (dummyProfile) oyProfile_Release(&dummyProfile); return; } oyOptions_Release(&options); error = oyOptions_SetFromText(&options, "//"OY_TYPE_STD"/config/display_mode", "1", OY_CREATE_NEW); if (error) { kWarning() << "Oy options error:" << error; if (dummyProfile) oyProfile_Release(&dummyProfile); return; } error = oyConversion_Correct(conversion, "//"OY_TYPE_STD"/icc", flags, options); if (error) { kWarning() << "Failed to correct conversion for" << m_outputName << "flags" << flags; if (dummyProfile) oyProfile_Release(&dummyProfile); return; } oyFilterGraph_s *conversionGraph = oyConversion_GetGraph(conversion); oyFilterNode_s *iccNode = oyFilterGraph_GetNode(conversionGraph, -1, "///icc", 0); // See what to search for in the cache QByteArray entryText; const char *t = oyFilterNode_GetText(iccNode, oyNAME_NAME); if (t) entryText = t; oyStructList_s *cache = Display::getInstance()->cache(); oyHash_s *entry = oyStructList_GetHash(cache, 0, entryText.constData()); oyArray2d_s *oyClut = (oyArray2d_s*) oyHash_GetPointer(entry, oyOBJECT_ARRAY2D_S); char ** array2d = (char**)oyArray2d_GetData( oyClut ); oyFilterNode_Release(&iccNode); oyFilterGraph_Release(&conversionGraph); if (oyClut) { // Found in cache kDebug() << "clut" << oyClut << "obtained from cache using entry" << entryText; memcpy(m_clut.data(), array2d[0], CLUT_DATA_SIZE); } else { kDebug() << "clut not found in cache using entry" << entryText << ", doing conversion"; // Create dummy / identity clut data for conversion input buildDummyClut(m_clut); // Do conversion error = oyConversion_RunPixels(conversion, 0); if (error) { kWarning() << "Output" << m_outputName << "Error" << error << "in conversion run pixels"; if (dummyProfile) oyProfile_Release(&dummyProfile); return; } // Save to cache oyClut = oyArray2d_Create( NULL, LUT_GRID_POINTS * 3, LUT_GRID_POINTS * LUT_GRID_POINTS, oyUINT16, NULL); array2d = (char**)oyArray2d_GetData( oyClut ); memcpy(array2d[0], m_clut.data(), CLUT_DATA_SIZE); oyHash_SetPointer(entry, (oyStruct_s*) oyClut); } oyOptions_Release(&options); oyImage_Release(&imageIn); oyImage_Release(&imageOut); oyConversion_Release(&conversion); if (!m_dstProfile) kDebug() << "Output" << m_outputName << "no profile"; }