/** @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;
}
Esempio n. 2
0
oyConversion_s * oyConversion_FromImageForDisplay_ (
                                       oyImage_s         * image_in,
                                       oyImage_s         * image_out,
                                       oyFilterNode_s   ** cc_node,
                                       uint32_t            flags,
                                       oyDATATYPE_e        data_type,
                                       oyOptions_s       * cc_options,
                                       oyObject_s          obj )
{
  oyFilterNode_s * in = 0, * out = 0, * icc = 0;
  int error = 0;
  oyConversion_s * conversion = 0;
  oyOptions_s * options = 0;
  oyOption_s * option = 0;
  const char * sv = 0;
  double scale = 0;

  if(!image_in || !image_out)
    return NULL;

  /* start with an empty conversion object */
  conversion = oyConversion_New( obj );
  /* create a filter node */
  in = oyFilterNode_NewWith( "//" OY_TYPE_STD "/root", 0, obj );
  /* set the above filter node as the input */
  oyConversion_Set( conversion, in, 0 );
  /* set the image buffer */
  oyFilterNode_SetData( in, (oyStruct_s*)image_in, 0, 0 );


  /* add a scale node */
  out = oyFilterNode_NewWith( "//" OY_TYPE_STD "/scale", 0, obj );
  options = oyFilterNode_GetOptions( out, OY_SELECT_FILTER );
  /* scale factor from DB */
  option = oyOption_FromRegistration( OY_INTERNAL "/scale/scale", 0 );
  error = oyOption_SetFromText( option, 0, 0 );
  error = oyOption_SetValueFromDB( option );
  scale = 1.0;
  if(!error)
  {
    sv = oyOption_GetValueString( option, 0 );
    if(sv)
      scale = strtod( sv, 0 );
  }
  oyOption_Release( &option );
  error = oyOptions_SetFromDouble( &options,
                                   OY_INTERNAL "/scale/scale",
                                   scale, 0, OY_CREATE_NEW );
  oyOptions_Release( &options );
  /* append the node */
  error = oyFilterNode_Connect( in, "//" OY_TYPE_STD "/data",
                                out, "//" OY_TYPE_STD "/data", 0 );
  if(error > 0)
    fprintf( stderr, "could not add  filter: %s\n", "//" OY_TYPE_STD "/scale" );
  in = out;


  /* add a expose node */
  out = oyFilterNode_NewWith( "//" OY_TYPE_STD "/expose", 0, obj );
  options = oyFilterNode_GetOptions( out, OY_SELECT_FILTER );
  /* expose factor */
  error = oyOptions_SetFromDouble( &options,
                                   "//" OY_TYPE_STD "/expose/expose",
                                   1.0, 0, OY_CREATE_NEW );
  oyOptions_Release( &options );
  /* append the node */
  error = oyFilterNode_Connect( in, "//" OY_TYPE_STD "/data",
                                out, "//" OY_TYPE_STD "/data", 0 );
  if(error > 0)
    fprintf( stderr, "could not add  filter: %s\n", "//" OY_TYPE_STD "/expose" );
  in = out;


  /* add a channel node */
  out = oyFilterNode_NewWith( "//" OY_TYPE_STD "/channel", 0, obj );
  options = oyFilterNode_GetOptions( out, OY_SELECT_FILTER );
  /* channel option*/
  error = oyOptions_SetFromText( &options,
                                   "//" OY_TYPE_STD "/channel/channel",
                                   "", OY_CREATE_NEW );
  oyOptions_Release( &options );
  /* append the node */
  error = oyFilterNode_Connect( in, "//" OY_TYPE_STD "/data",
                                out, "//" OY_TYPE_STD "/data", 0 );
  if(error > 0)
    fprintf( stderr, "could not add  filter: %s\n", "//" OY_TYPE_STD "/channel" );
  in = out;


  /* create a new filter node */
  {
    icc = out = oyFilterNode_FromOptions( OY_CMM_STD, "//" OY_TYPE_STD "/icc_color",
                                     cc_options, NULL );
    /* append the new to the previous one */
    error = oyFilterNode_Connect( in, "//" OY_TYPE_STD "/data",
                                  out, "//" OY_TYPE_STD "/data", 0 );
    if(error > 0)
      fprintf( stderr, "could not add  filter: %s\n", OY_CMM_STD );

    /* Set the image to the first/only socket of the filter node.
     * oyFilterNode_Connect() has now no chance to copy it it the other nodes.
     * We rely on resolving the image later.
     */
    error = oyFilterNode_SetData( out, (oyStruct_s*)image_out, 0, 0 );
    if(error != 0)
      fprintf( stderr, "could not add data\n" );
  }

  /* swap in and out */
  if(out)
    in = out;


  /* create a node for preparing the image for displaying */
  {
    out = oyFilterNode_NewWith( "//" OY_TYPE_STD "/display", 0, obj );
    options = oyFilterNode_GetOptions( out, OY_SELECT_FILTER );
    /* data type for display */
    error = oyOptions_SetFromInt( &options,
                                  "//" OY_TYPE_STD "/display/datatype",
                                  data_type, 0, OY_CREATE_NEW );
    /* alpha might be support once by FLTK? */
    error = oyOptions_SetFromInt( &options,
                                  "//" OY_TYPE_STD "/display/preserve_alpha",
                                  1, 0, OY_CREATE_NEW );
    oyOptions_Release( &options );
    /* append the node */
    error = oyFilterNode_Connect( in, "//" OY_TYPE_STD "/data",
                                  out, "//" OY_TYPE_STD "/data", 0 );
    if(error > 0)
      fprintf( stderr, "could not add  filter: %s\n", "//" OY_TYPE_STD "/display" );
    oyFilterNode_SetData( out, (oyStruct_s*)image_out, 0, 0 );
    in = out;
  }


  /* add a closing node */
  out = oyFilterNode_NewWith( "//" OY_TYPE_STD "/output", 0, obj );
  error = oyFilterNode_Connect( in, "//" OY_TYPE_STD "/data",
                                out, "//" OY_TYPE_STD "/data", 0 );
  if(error > 0)
    fprintf( stderr, "could not add  filter: %s\n", "//" OY_TYPE_STD "/output" );

  /* set the output node of the conversion */
  oyConversion_Set( conversion, 0, out );

  /* apply policies */
  /*error = oyOptions_SetFromText( &options, "//" OY_TYPE_STD "//verbose",
                                 "true", OY_CREATE_NEW );*/
  oyConversion_Correct( conversion, "//" OY_TYPE_STD "/icc_color", flags,
                        options );
  oyOptions_Release( &options );

  if(cc_node)
    *cc_node = icc;

  return conversion;
}
/** @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;
}