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; }
/** @func oyraFilterPlug_ImageOutputPPMWrite * @brief implement oyCMMFilter_GetNext_f() * * @version Oyranos: 0.3.1 * @since 2008/10/07 (Oyranos: 0.1.8) * @date 2011/05/12 */ int oyraFilterPlug_ImageOutputPPMWrite ( oyFilterPlug_s * requestor_plug, oyPixelAccess_s * ticket ) { oyFilterSocket_s * socket; oyFilterNode_s * node = 0; oyOptions_s * node_opts = 0; int result = 0; const char * filename = 0; FILE * fp = 0; socket = oyFilterPlug_GetSocket( requestor_plug ); node = oyFilterSocket_GetNode( socket ); node_opts = oyFilterNode_GetOptions( node, 0 ); /* to reuse the requestor_plug is a exception for the starting request */ if(node) result = oyFilterNode_Run( node, requestor_plug, ticket ); else result = 1; if(result <= 0) filename = oyOptions_FindString( node_opts, "filename", 0 ); if(filename) fp = fopen( filename, "wb" ); if(fp) { oyImage_s *image_output = (oyImage_s*)oyFilterSocket_GetData( socket ); const char * comment = oyOptions_FindString( node_opts, "comment", NULL ); fclose (fp); fp = 0; result = oyImage_WritePPM( image_output, filename, comment ? comment : oyFilterNode_GetRelatives( node ) ); } return result; }
int oyProfile_CreateEffectVCGT ( oyProfile_s * prof ) { int error = 0; /* 2. get user effect profile and display white point effect */ /* 2.1. get effect profile and decide if it can be embedded into a VGCT tag */ oyOptions_s * module_options = NULL; error = oyAddLinearDisplayEffect( &module_options ); if(error) oyMessageFunc_p( oyMSG_WARN,(oyStruct_s*)prof, OY_DBG_FORMAT_ "No display effect for monitor profile %d", OY_DBG_ARGS_, error ); /* 2.2. get the display white point effect */ error = oyProfileAddWhitePointEffect( prof, &module_options ); if(error) oyMessageFunc_p( oyMSG_WARN,(oyStruct_s*)prof, OY_DBG_FORMAT_ "No white for monitor profile %d", OY_DBG_ARGS_, error ); /* 3. extract a existing VCGT */ int width = 256; uint16_t * vcgt = oyProfile_GetVCGT( prof, &width ); oyImage_s * img; if(vcgt && getenv("OY_DEBUG_WRITE")) { img = oyImage_Create( width, 1, vcgt, OY_TYPE_123_16, prof, 0 ); oyImage_WritePPM( img, "wtpt-vcgt.ppm", "vcgt ramp" ); oyImage_Release( &img ); } /* 4. create conversion, fill ramp and convert */ uint16_t * ramp = oyProfileGetWhitePointRamp( width, prof, module_options ); if(ramp && getenv("OY_DEBUG_WRITE")) { img = oyImage_Create( width, 1, ramp, OY_TYPE_123_16, prof, 0 ); oyImage_WritePPM( img, "wtpt-effect.ppm", "white point ramp" ); oyImage_Release( &img ); } /* 5. mix the two ramps */ uint16_t * mix = NULL; if(vcgt) mix = calloc( sizeof(uint16_t), width*3); int i,j; if(mix) for(i = 0; i < width; ++i) for(j = 0; j < 3; ++j) { uint16_t v = oyLinInterpolateRampU16c( ramp, width, j, 3, (double)i/(double)width ); double vd = v / 65535.0; mix[i*3+j] = OY_ROUNDp( oyLinInterpolateRampU16c( vcgt, width, j,3, vd ) ); } if(mix && getenv("OY_DEBUG_WRITE")) { img = oyImage_Create( width, 1, mix, OY_TYPE_123_16, prof, 0 ); oyImage_WritePPM( img, "wtpt-mix.ppm", "white point + vcgt" ); oyImage_Release( &img ); } /* 6. create a new VCGT tag and exchange the tag */ if((mix || ramp) && oyProfile_SetVCGT( prof, mix?mix:ramp, width )) { oyMessageFunc_p( oyMSG_WARN,(oyStruct_s*)prof, OY_DBG_FORMAT_ "Alter VCGT tag failed", OY_DBG_ARGS_ ); error = 1; } if(mix) oyDeAllocateFunc_(mix); if(ramp) oyDeAllocateFunc_(ramp); if(vcgt) oyDeAllocateFunc_(vcgt); 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; }