/**
 *  @internal
 *  Function: oyColorConvert_
 *  @memberof oyNamedColor_s
 *  @brief   convert colors
 *
 *  The options are passed to oyConversion_CreateBasicPixels();
 *  The function does the lookups for the profiles and the modules contexts
 *  in the Oyranos cache on the fly. The allocated oyImage_s and
 *  oyConversion_s structures are not cheap as they are not cached.
 *
 *  @version Oyranos: 0.1.11
 *  @since   2007/12/23 (Oyranos: 0.1.8)
 *  @date    2010/09/10
 */
int  oyColorConvert_  ( oyProfile_s       * p_in,
                        oyProfile_s       * p_out,
                        oyPointer           buf_in,
                        oyPointer           buf_out,
                        oyDATATYPE_e        buf_type_in,
                        oyDATATYPE_e        buf_type_out,
                        oyOptions_s       * options,
                        int                 count )
{
  oyImage_s * in  = NULL,
            * out = NULL;
  oyConversion_s * conv = NULL;
  int error = 0;

  in    = oyImage_Create( count, 1,
                         buf_in ,
                         oyChannels_m(oyProfile_GetChannelsCount(p_in)) |
                          oyDataType_m(buf_type_in),
                         p_in,
                         0 );
  out   = oyImage_Create( count, 1,
                         buf_out ,
                         oyChannels_m(oyProfile_GetChannelsCount(p_out)) |
                          oyDataType_m(buf_type_out),
                         p_out,
                         0 );

  conv   = oyConversion_CreateBasicPixels( in,out, options, 0 );
  error  = oyConversion_RunPixels( conv, 0 );

  oyConversion_Release( &conv );
  oyImage_Release( &in );
  oyImage_Release( &out );

  return error;
}
Ejemplo n.º 2
0
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";
}