Пример #1
0
static GtkWidget *
lcms_icc_combo_box_new (GimpColorConfig *config,
                        const gchar     *filename)
{
  GtkWidget   *combo;
  GtkWidget   *dialog;
  gchar       *history;
  gchar       *label;
  gchar       *name;
  cmsHPROFILE  profile;

  dialog = lcms_icc_file_chooser_dialog_new ();
  history = gimp_personal_rc_file ("profilerc");

  combo = gimp_color_profile_combo_box_new (dialog, history);

  g_free (history);

  g_signal_connect (dialog, "response",
                    G_CALLBACK (lcms_icc_file_chooser_dialog_response),
                    combo);

  if (config->rgb_profile)
    profile = lcms_load_profile (config->rgb_profile, NULL);
  else
    profile = cmsCreate_sRGBProfile ();

  name = lcms_icc_profile_get_desc (profile);
  if (! name)
    name = lcms_icc_profile_get_name (profile);

  cmsCloseProfile (profile);

  label = g_strdup_printf (_("RGB workspace (%s)"), name);
  g_free (name);

  gimp_color_profile_combo_box_add (GIMP_COLOR_PROFILE_COMBO_BOX (combo),
                                    config->rgb_profile, label);
  g_free (label);

  if (filename)
    lcms_icc_combo_box_set_active (GIMP_COLOR_PROFILE_COMBO_BOX (combo),
                                   filename);
  else
    gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);

  return combo;
}
Пример #2
0
 void GetMonitorProfile(wxString& profileName, cmsHPROFILE& profile)
 {
     if (profile != NULL)
     {
         cmsCloseProfile(profile);
     }
     profileName.Clear();
     profile = NULL;
     detail::GetMonitorProfile(profileName, profile);
     // check if monitor profile could be successful loaded, if not switch back to default sRGB profile
     if (profile == NULL)
     {
         profile = cmsCreate_sRGBProfile();
         profileName.Clear();
     };
 };
Пример #3
0
static PyObject *
pycms_CreateRGBProfile(PyObject *self, PyObject *args) {

	cmsHPROFILE hProfile;

	cmsErrorAction(LCMS_ERROR_IGNORE);

	hProfile = cmsCreate_sRGBProfile();

	if(hProfile==NULL) {
		Py_INCREF(Py_None);
		return Py_None;
	}

	return Py_BuildValue("O", PyCObject_FromVoidPtr((void *)hProfile, (void *)cmsCloseProfile));
}
Пример #4
0
/******************************************************************************
 * CreateColorTransformW            [[email protected]]
 *
 * Create a color transform.
 *
 * PARAMS
 *  space  [I] Input color space.
 *  dest   [I] Color profile of destination device.
 *  target [I] Color profile of target device.
 *  flags  [I] Flags.
 *
 * RETURNS
 *  Success: Handle to a transform.
 *  Failure: NULL
 */
HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest,
    HPROFILE target, DWORD flags )
{
    HTRANSFORM ret = NULL;
#ifdef HAVE_LCMS
    struct transform transform;
    struct profile *dst, *tgt = NULL;
    cmsHPROFILE cmsinput, cmsoutput, cmstarget = NULL;
    DWORD in_format, out_format, proofing = 0;
    int intent;

    TRACE( "( %p, %p, %p, 0x%08x )\n", space, dest, target, flags );

    if (!space || !(dst = grab_profile( dest ))) return FALSE;

    if (target && !(tgt = grab_profile( target )))
    {
        release_profile( dst );
        return FALSE;
    }
    intent = space->lcsIntent > 3 ? INTENT_PERCEPTUAL : space->lcsIntent;

    TRACE( "lcsIntent:   %x\n", space->lcsIntent );
    TRACE( "lcsCSType:   %s\n", MSCMS_dbgstr_tag( space->lcsCSType ) );
    TRACE( "lcsFilename: %s\n", debugstr_w( space->lcsFilename ) );

    in_format  = TYPE_RGB_16;
    out_format = from_profile( dest );

    cmsinput = cmsCreate_sRGBProfile(); /* FIXME: create from supplied color space */
    if (target)
    {
        proofing = cmsFLAGS_SOFTPROOFING;
        cmstarget = tgt->cmsprofile;
    }
    cmsoutput = dst->cmsprofile;
    transform.cmstransform = cmsCreateProofingTransform(cmsinput, in_format, cmsoutput, out_format, cmstarget,
                                                        intent, INTENT_ABSOLUTE_COLORIMETRIC, proofing);

    ret = create_transform( &transform );

    if (tgt) release_profile( tgt );
    release_profile( dst );

#endif /* HAVE_LCMS */
    return ret;
}
Пример #5
0
LCMS_ICCProfile* LCMS_ColorManager::GetDeviceProfile()
{
	if (!m_srgb_profile)
	{
		m_srgb_profile = OP_NEW(LCMS_ICCProfile, ());
		if (m_srgb_profile)
		{
			cmsHPROFILE profile = cmsCreate_sRGBProfile();
			if (!profile)
			{
				OP_DELETE(m_srgb_profile);
				m_srgb_profile = NULL;
			}
			else
			{
				m_srgb_profile->m_profile = profile;
			}
		}
	}
Пример #6
0
static PyObject *
createProfile(PyObject *self, PyObject *args)
{
    char *sColorSpace;
    cmsHPROFILE hProfile;
    int iColorTemp = 0;
    LPcmsCIExyY whitePoint = NULL;
    LCMSBOOL result;

    if (!PyArg_ParseTuple(args, "s|i:createProfile", &sColorSpace, &iColorTemp))
        return NULL;

    cmsErrorAction(LCMS_ERROR_IGNORE);

    if (strcmp(sColorSpace, "LAB") == 0) {
        if (iColorTemp > 0) {
            result = cmsWhitePointFromTemp(iColorTemp, whitePoint);
            if (!result) {
                PyErr_SetString(PyExc_ValueError,"ERROR: Could not calculate "\
                    "white point from color temperature provided, must be "\
                    "integer in degrees Kelvin");
                return NULL;
            }
            hProfile = cmsCreateLabProfile(whitePoint);
        } else
            hProfile = cmsCreateLabProfile(NULL);
    }
    else if (strcmp(sColorSpace, "XYZ") == 0)
        hProfile = cmsCreateXYZProfile();
    else if (strcmp(sColorSpace, "sRGB") == 0)
        hProfile = cmsCreate_sRGBProfile();
    else
        hProfile = NULL;

    if (!hProfile) {
        PyErr_SetString(PyExc_ValueError,
            "failed to create requested color space");
        return NULL;
    }

    return cms_profile_new(hProfile);
}
Пример #7
0
static PyObject *
createProfile(PyObject *self, PyObject *args)
{
    char *sColorSpace;
    cmsHPROFILE hProfile;
    cmsFloat64Number dColorTemp = 0.0;
    cmsCIExyY whitePoint;
    cmsBool result;

    if (!PyArg_ParseTuple(args, "s|d:createProfile", &sColorSpace, &dColorTemp))
        return NULL;

    if (strcmp(sColorSpace, "LAB") == 0) {
        if (dColorTemp > 0.0) {
            result = cmsWhitePointFromTemp(&whitePoint, dColorTemp);
            if (!result) {
                PyErr_SetString(PyExc_ValueError, "ERROR: Could not calculate white point from color temperature provided, must be float in degrees Kelvin");
                return NULL;
            }
            hProfile = cmsCreateLab2Profile(&whitePoint);
        } else {
            hProfile = cmsCreateLab2Profile(NULL);
        }
    }
    else if (strcmp(sColorSpace, "XYZ") == 0) {
        hProfile = cmsCreateXYZProfile();
    }
    else if (strcmp(sColorSpace, "sRGB") == 0) {
        hProfile = cmsCreate_sRGBProfile();
    }
    else {
        hProfile = NULL;
    }

    if (!hProfile) {
        PyErr_SetString(PyExc_ValueError, "failed to create requested color space");
        return NULL;
    }

    return cms_profile_new(hProfile);
}
Пример #8
0
static void
cdisplay_proof_changed (GimpColorDisplay *display)
{
  CdisplayProof *proof = CDISPLAY_PROOF (display);
  cmsHPROFILE    rgbProfile;
  cmsHPROFILE    proofProfile;

  if (proof->transform)
    {
      cmsDeleteTransform (proof->transform);
      proof->transform = NULL;
    }

  if (! proof->profile)
    return;

  rgbProfile = cmsCreate_sRGBProfile ();

  proofProfile = cmsOpenProfileFromFile (proof->profile, "r");

  if (proofProfile)
    {
      DWORD flags = cmsFLAGS_SOFTPROOFING;

      if (proof->bpc)
        flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;

      proof->transform = cmsCreateProofingTransform (rgbProfile,
                                                     TYPE_RGB_8,
                                                     rgbProfile, TYPE_RGB_8,
                                                     proofProfile,
                                                     proof->intent,
                                                     proof->intent,
                                                     flags);

      cmsCloseProfile (proofProfile);
    }

  cmsCloseProfile (rgbProfile);
}
Пример #9
0
ScColorProfile ScLcms2ColorMgmtEngineImpl::createProfile_sRGB(ScColorMgmtEngine& engine)
{
	QString internalProfilePath("memprofile://Internal sRGB profile");
	ScColorProfile profile = m_profileCache->profile(internalProfilePath);
	if (!profile.isNull())
		return profile;

	cmsHPROFILE lcmsProf = cmsCreate_sRGBProfile();
	if (lcmsProf)
	{
		ScLcms2ColorProfileImpl* profData = new ScLcms2ColorProfileImpl(engine, lcmsProf);
		profData->m_profilePath = internalProfilePath;
		profile = ScColorProfile(dynamic_cast<ScColorProfileData*>(profData));
		m_profileCache->addProfile(profile);
	}
	if (profile.isNull() && lcmsProf)
	{
		cmsCloseProfile(lcmsProf);
		lcmsProf = NULL;
	}
	return profile;
}
Пример #10
0
Profile::Ptr Profile::getMonitorProfile()
{
    cmsHPROFILE hProfile = 0;
    // Get the profile from you config file if the user has set it.
    // if the user allows override through the atom, do this:
#ifdef Q_WS_X11

    // get the current screen...
    int screen = -1;

    Atom type;
    int format;
    unsigned long nitems;
    unsigned long bytes_after;
    quint8 *str;

    static Atom icc_atom = XInternAtom(QX11Info::display(), "_ICC_PROFILE", True);

    if (XGetWindowProperty(QX11Info::display(),
                            QX11Info::appRootWindow(screen),
                            icc_atom,
                            0,
                            INT_MAX,
                            False,
                            XA_CARDINAL,
                            &type,
                            &format,
                            &nitems,
                            &bytes_after,
                            (unsigned char **) &str) == Success
    ) {
        hProfile = cmsOpenProfileFromMem((void*)str, nitems);
    }
#endif
    if (!hProfile) {
        hProfile = cmsCreate_sRGBProfile();
    }
    return Profile::Ptr(new Profile(hProfile));
}
Пример #11
0
void TestKoLcmsColorProfile::testConversion()
{
    const KoColorSpace *sRgb = KoColorSpaceRegistry::instance()->rgb16("sRGB built-in");
    Q_ASSERT(sRgb);
    const KoColorSpace *linearRgb = KoColorSpaceRegistry::instance()->rgb16("scRGB (linear)");
    Q_ASSERT(linearRgb);

    quint16 src[4];
    src[0] = 257;
    src[1] = 257;
    src[2] = 257;
    src[3] = 65535;

    quint16 dst[4];
    memset(&dst, 0, 8);

    linearRgb->convertPixelsTo((quint8 *)&src, (quint8 *)&dst, sRgb, 1, KoColorConversionTransformation::IntentRelativeColorimetric, KoColorConversionTransformation::BlackpointCompensation);

    quint16 dst2[4];
    memset(&dst2, 0, 8);

    cmsHPROFILE sRgbProfile = cmsCreate_sRGBProfile();
    QByteArray rawData = linearRgb->profile()->rawData();
    cmsHPROFILE linearRgbProfile = cmsOpenProfileFromMem((void *)rawData.constData(), rawData.size());

    cmsHTRANSFORM tf = cmsCreateTransform(linearRgbProfile,
                                          TYPE_BGRA_16,
                                          sRgbProfile,
                                          TYPE_BGRA_16,
                                          INTENT_RELATIVE_COLORIMETRIC,
                                          cmsFLAGS_NOOPTIMIZE);

    cmsDoTransform(tf, (quint8 *)&src, (quint8 *)&dst2, 1);

    Q_ASSERT(dst[0] == dst2[0]);

}
Пример #12
0
static cmsHTRANSFORM
cd_sensor_get_fake_transform (CdSensorDummyPrivate *priv)
{
	cmsHTRANSFORM transform;
	cmsHPROFILE profile_srgb;
	cmsHPROFILE profile_xyz;

	profile_srgb = cmsCreate_sRGBProfile ();
	profile_xyz = cmsCreateXYZProfile ();
	transform = cmsCreateTransform (profile_srgb, TYPE_RGB_DBL,
					profile_xyz, TYPE_XYZ_DBL,
					INTENT_RELATIVE_COLORIMETRIC,
					cmsFLAGS_NOOPTIMIZE);
	if (transform == NULL) {
		g_warning ("failed to setup RGB -> XYZ transform");
		goto out;
	}
out:
	if (profile_srgb != NULL)
		cmsCloseProfile (profile_srgb);
	if (profile_xyz != NULL)
		cmsCloseProfile (profile_xyz);
	return transform;
}
Пример #13
0
static cmsHPROFILE color_man_cache_load_profile(ColorManProfileType type, const gchar *file,
						guchar *data, guint data_len)
{
	cmsHPROFILE profile = NULL;

	switch (type)
		{
		case COLOR_PROFILE_FILE:
			if (file)
				{
				gchar *pathl;

				pathl = path_from_utf8(file);
				profile = cmsOpenProfileFromFile(pathl, "r");
				g_free(pathl);
				}
			break;
		case COLOR_PROFILE_SRGB:
			profile = cmsCreate_sRGBProfile();
			break;
		case COLOR_PROFILE_ADOBERGB:
			profile = color_man_create_adobe_comp();
			break;
		case COLOR_PROFILE_MEM:
			if (data)
				{
				profile = cmsOpenProfileFromMem(data, data_len);
				}
			break;
		case COLOR_PROFILE_NONE:
		default:
			break;
		}

	return profile;
}
Пример #14
0
        void CorrectImage(wxImage& image, const vigra::ImageImportInfo::ICCProfile& iccProfile, const cmsHPROFILE& monitorProfile)
        {
            cmsHPROFILE inputICC = NULL;
            if (!iccProfile.empty())
            {
                inputICC = cmsOpenProfileFromMem(iccProfile.data(), iccProfile.size());
            };
            // check type of input profile
            if (inputICC != NULL)
            {
                if (cmsGetColorSpace(inputICC) != cmsSigRgbData)
                {
                    cmsCloseProfile(inputICC);
                    inputICC = NULL;
                };
            };
            // if there is no icc profile in file fall back to sRGB
            if (inputICC == NULL)
            {
                inputICC = cmsCreate_sRGBProfile();
            };
            // now build transform
            cmsHTRANSFORM transform = cmsCreateTransform(inputICC, TYPE_RGB_8,
                monitorProfile, TYPE_RGB_8,
                INTENT_PERCEPTUAL, cmsFLAGS_BLACKPOINTCOMPENSATION);
            unsigned char* imgData = image.GetData();
            const int imgWidth = image.GetWidth();
            const int imgHeight = image.GetHeight();
#pragma omp parallel for
            for (int y = 0; y < imgHeight; ++y)
            {
                cmsDoTransform(transform, imgData + 3 * y * imgWidth, imgData + 3 * y * imgWidth, imgWidth);
            };
            cmsDeleteTransform(transform);
            cmsCloseProfile(inputICC);
        };
Пример #15
0
/******************************************************************************
 * CreateMultiProfileTransform      [[email protected]]
 *
 * Create a color transform from an array of color profiles.
 *
 * PARAMS
 *  profiles  [I] Array of color profiles.
 *  nprofiles [I] Number of color profiles.
 *  intents   [I] Array of rendering intents.
 *  flags     [I] Flags.
 *  cmm       [I] Profile to take the CMM from.
 *
 * RETURNS
 *  Success: Handle to a transform.
 *  Failure: NULL
 */ 
HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofiles,
    PDWORD intents, DWORD nintents, DWORD flags, DWORD cmm )
{
    HTRANSFORM ret = NULL;
#ifdef HAVE_LCMS
    cmsHPROFILE *cmsprofiles, cmsconvert = NULL;
    struct transform transform;
    struct profile *profile0, *profile1;
    DWORD in_format, out_format;

    TRACE( "( %p, 0x%08x, %p, 0x%08x, 0x%08x, 0x%08x )\n",
           profiles, nprofiles, intents, nintents, flags, cmm );

    if (!profiles || !nprofiles || !intents) return NULL;

    if (nprofiles > 2)
    {
        FIXME("more than 2 profiles not supported\n");
        return NULL;
    }

    profile0 = grab_profile( profiles[0] );
    if (!profile0) return NULL;
    profile1 = grab_profile( profiles[1] );
    if (!profile1)
    {
        release_profile( profile0 );
        return NULL;
    }
    in_format  = from_profile( profiles[0] );
    out_format = from_profile( profiles[nprofiles - 1] );

    if (in_format != out_format)
    {
        /* insert a conversion profile for pairings that lcms doesn't handle */
        if (out_format == TYPE_RGB_16) cmsconvert = cmsCreate_sRGBProfile();
        if (out_format == TYPE_Lab_16) cmsconvert = cmsCreateLabProfile( NULL );
    }

    cmsprofiles = HeapAlloc( GetProcessHeap(), 0, (nprofiles + 1) * sizeof(cmsHPROFILE) );
    if (cmsprofiles)
    {
        cmsprofiles[0] = profile0->cmsprofile;
        if (cmsconvert)
        {
            cmsprofiles[1] = cmsconvert;
            cmsprofiles[2] = profile1->cmsprofile;
            nprofiles++;
        }
        else
        {
            cmsprofiles[1] = profile1->cmsprofile;
        }
        transform.cmstransform = cmsCreateMultiprofileTransform( cmsprofiles, nprofiles, in_format, out_format, *intents, 0 );

        HeapFree( GetProcessHeap(), 0, cmsprofiles );
        ret = create_transform( &transform );
    }

    release_profile( profile0 );
    release_profile( profile1 );

#endif /* HAVE_LCMS */
    return ret;
}
Пример #16
0
static gpointer
jpeg_load_cmyk_transform (guint8 *profile_data,
                          gsize   profile_len)
{
#ifdef HAVE_LCMS
  GimpColorConfig *config       = gimp_get_color_configuration ();
  cmsHPROFILE      cmyk_profile = NULL;
  cmsHPROFILE      rgb_profile  = NULL;
  cmsUInt32Number  flags        = 0;
  cmsHTRANSFORM    transform;

  /*  try to load the embedded CMYK profile  */
  if (profile_data)
    {
      cmyk_profile = cmsOpenProfileFromMem (profile_data, profile_len);

      if (cmyk_profile)
        {
#ifdef HAVE_LCMS1
          if (cmsGetColorSpace (cmyk_profile) != icSigCmykData)
#else
          if (cmsGetColorSpace (cmyk_profile) != cmsSigCmykData)
#endif
            {
              cmsCloseProfile (cmyk_profile);
              cmyk_profile = NULL;
            }
        }
    }

  /*  if that fails, try to load the CMYK profile configured in the prefs  */
  if (! cmyk_profile && config->cmyk_profile)
    {
      cmyk_profile = cmsOpenProfileFromFile (config->cmyk_profile, "r");

#ifdef HAVE_LCMS1
      if (cmyk_profile && cmsGetColorSpace (cmyk_profile) != icSigCmykData)
#else
      if (cmyk_profile && cmsGetColorSpace (cmyk_profile) != cmsSigCmykData)
#endif
        {
          cmsCloseProfile (cmyk_profile);
          cmyk_profile = NULL;
        }
    }

  /*  bail out if we can't load any CMYK profile  */
  if (! cmyk_profile)
    {
      g_object_unref (config);
      return NULL;
    }

  /*  try to load the RGB profile configured in the prefs  */
  if (config->rgb_profile)
    {
      rgb_profile = cmsOpenProfileFromFile (config->rgb_profile, "r");

#ifdef HAVE_LCMS1
      if (rgb_profile && cmsGetColorSpace (rgb_profile) != icSigRgbData)
#else
      if (rgb_profile && cmsGetColorSpace (rgb_profile) != cmsSigRgbData)
#endif
        {
          cmsCloseProfile (rgb_profile);
          rgb_profile = NULL;
        }
    }

  /*  use the built-in sRGB profile as fallback  */
  if (! rgb_profile)
    {
      rgb_profile = cmsCreate_sRGBProfile ();
    }

  if (config->display_intent ==
      GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC)
    {
      flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
    }

  transform = cmsCreateTransform (cmyk_profile, TYPE_CMYK_8_REV,
                                  rgb_profile,  TYPE_RGB_8,
                                  config->display_intent,
                                  flags);

  cmsCloseProfile (cmyk_profile);
  cmsCloseProfile (rgb_profile);

  g_object_unref (config);

  return transform;
#else  /* HAVE_LCMS */
  return NULL;
#endif
}
Пример #17
0
static GimpPDBStatusType
lcms_icc_apply (GimpColorConfig          *config,
                GimpRunMode               run_mode,
                gint32                    image,
                const gchar              *filename,
                GimpColorRenderingIntent  intent,
                gboolean                  bpc,
                gboolean                 *dont_ask)
{
  GimpPDBStatusType status       = GIMP_PDB_SUCCESS;
  cmsHPROFILE       src_profile  = NULL;
  cmsHPROFILE       dest_profile = NULL;
  guchar            src_md5[16];
  guchar            dest_md5[16];

  g_return_val_if_fail (GIMP_IS_COLOR_CONFIG (config), GIMP_PDB_CALLING_ERROR);
  g_return_val_if_fail (image != -1, GIMP_PDB_CALLING_ERROR);

  if (! filename)
    filename = config->rgb_profile;

  if (filename)
    {
      dest_profile = lcms_load_profile (filename, dest_md5);

      if (! dest_profile)
        return GIMP_PDB_EXECUTION_ERROR;

      if (! lcms_icc_profile_is_rgb (dest_profile))
        {
          g_message (_("Color profile '%s' is not for RGB color space."),
                     gimp_filename_to_utf8 (filename));

          cmsCloseProfile (dest_profile);
          return GIMP_PDB_EXECUTION_ERROR;
        }
    }

  src_profile = lcms_image_get_profile (config, image, src_md5);

  if (src_profile && ! lcms_icc_profile_is_rgb (src_profile))
    {
      g_printerr ("lcms: attached color profile is not for RGB color space "
                  "(skipping)\n");

      cmsCloseProfile (src_profile);
      src_profile = NULL;
    }

  if (! src_profile && ! dest_profile)
    return GIMP_PDB_SUCCESS;

  if (! src_profile)
    {
      src_profile = cmsCreate_sRGBProfile ();
      lcms_sRGB_checksum (src_md5);
    }

  if (! dest_profile)
    {
      dest_profile = cmsCreate_sRGBProfile ();
      lcms_sRGB_checksum (dest_md5);
    }

  if (memcmp (src_md5, dest_md5, 16) == 0)
    {
      gchar *src_desc  = lcms_icc_profile_get_desc (src_profile);
      gchar *dest_desc = lcms_icc_profile_get_desc (dest_profile);

      cmsCloseProfile (src_profile);
      cmsCloseProfile (dest_profile);

      g_printerr ("lcms: skipping conversion because profiles seem to be equal:\n");
      g_printerr (" %s\n", src_desc);
      g_printerr (" %s\n", dest_desc);

      g_free (src_desc);
      g_free (dest_desc);

      return GIMP_PDB_SUCCESS;
    }

  if (run_mode == GIMP_RUN_INTERACTIVE &&
      ! lcms_icc_apply_dialog (image, src_profile, dest_profile, dont_ask))
    {
      status = GIMP_PDB_CANCEL;
    }

  if (status == GIMP_PDB_SUCCESS &&
      ! lcms_image_apply_profile (image,
                                  src_profile, dest_profile, filename,
                                  intent, bpc))
    {
      status = GIMP_PDB_EXECUTION_ERROR;
    }

  cmsCloseProfile (src_profile);
  cmsCloseProfile (dest_profile);

  return status;
}
Пример #18
0
static GimpPDBStatusType
lcms_dialog (GimpColorConfig *config,
             gint32           image,
             gboolean         apply,
             LcmsValues      *values)
{
  GimpColorProfileComboBox *box;
  GtkWidget                *dialog;
  GtkWidget                *main_vbox;
  GtkWidget                *frame;
  GtkWidget                *label;
  GtkWidget                *combo;
  cmsHPROFILE               src_profile;
  gchar                    *name;
  gboolean                  success = FALSE;
  gboolean                  run;

  src_profile = lcms_image_get_profile (config, image, NULL);

  if (src_profile && ! lcms_icc_profile_is_rgb (src_profile))
    {
      g_printerr ("lcms: attached color profile is not for RGB color space "
                  "(skipping)\n");

      cmsCloseProfile (src_profile);
      src_profile = NULL;
    }

  if (! src_profile)
    src_profile = cmsCreate_sRGBProfile ();

  gimp_ui_init (PLUG_IN_BINARY, FALSE);

  dialog = gimp_dialog_new (apply ?
                            _("Convert to ICC Color Profile") :
                            _("Assign ICC Color Profile"),
                            PLUG_IN_ROLE,
                            NULL, 0,
                            gimp_standard_help_func,
                            apply ? PLUG_IN_PROC_APPLY : PLUG_IN_PROC_SET,

                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,

                            apply ? GTK_STOCK_CONVERT : _("_Assign"),
                            GTK_RESPONSE_OK,

                            NULL);

  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
                                           GTK_RESPONSE_OK,
                                           GTK_RESPONSE_CANCEL,
                                           -1);

  gimp_window_set_transient (GTK_WINDOW (dialog));

  main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
  gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
  gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
                      main_vbox, TRUE, TRUE, 0);
  gtk_widget_show (main_vbox);

  frame = gimp_frame_new (_("Current Color Profile"));
  gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
  gtk_widget_show (frame);

  name = lcms_icc_profile_get_desc (src_profile);
  if (! name)
    name = lcms_icc_profile_get_name (src_profile);

  label = gtk_label_new (name);
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_container_add (GTK_CONTAINER (frame), label);
  gtk_widget_show (label);

  g_free (name);

  frame = gimp_frame_new (apply ? _("Convert to") : _("Assign"));
  gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
  gtk_widget_show (frame);

  combo = lcms_icc_combo_box_new (config, NULL);
  gtk_container_add (GTK_CONTAINER (frame), combo);
  gtk_widget_show (combo);

  box = GIMP_COLOR_PROFILE_COMBO_BOX (combo);

  if (apply)
    {
      GtkWidget *vbox;
      GtkWidget *hbox;
      GtkWidget *toggle;

      vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
      gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
      gtk_widget_show (vbox);

      hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
      gtk_widget_show (hbox);

      label = gtk_label_new_with_mnemonic (_("_Rendering Intent:"));
      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
      gtk_widget_show (label);

      combo = gimp_enum_combo_box_new (GIMP_TYPE_COLOR_RENDERING_INTENT);
      gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
      gtk_widget_show (combo);

      gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo),
                                  values->intent,
                                  G_CALLBACK (gimp_int_combo_box_get_active),
                                  &values->intent);

      gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);

      toggle =
        gtk_check_button_new_with_mnemonic (_("_Black Point Compensation"));
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), values->bpc);
      gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
      gtk_widget_show (toggle);

      g_signal_connect (toggle, "toggled",
                        G_CALLBACK (gimp_toggle_button_update),
                        &values->bpc);
    }

  while ((run = gimp_dialog_run (GIMP_DIALOG (dialog))) == GTK_RESPONSE_OK)
    {
      gchar       *filename = gimp_color_profile_combo_box_get_active (box);
      cmsHPROFILE  dest_profile;

      gtk_widget_set_sensitive (dialog, FALSE);

      if (filename)
        {
          dest_profile = lcms_load_profile (filename, NULL);
        }
      else
        {
          dest_profile = cmsCreate_sRGBProfile ();
        }

      if (dest_profile)
        {
          if (lcms_icc_profile_is_rgb (dest_profile))
            {
              if (apply)
                success = lcms_image_apply_profile (image,
                                                    src_profile, dest_profile,
                                                    filename,
                                                    values->intent,
                                                    values->bpc);
              else
                success = lcms_image_set_profile (image,
                                                  dest_profile, filename, TRUE);
            }
          else
            {
              gimp_message (_("Destination profile is not for RGB color space."));
            }

          cmsCloseProfile (dest_profile);
        }

      if (success)
        break;
      else
        gtk_widget_set_sensitive (dialog, TRUE);
    }

  gtk_widget_destroy (dialog);

  cmsCloseProfile (src_profile);

  return (run ?
          (success ? GIMP_PDB_SUCCESS : GIMP_PDB_EXECUTION_ERROR) :
          GIMP_PDB_CANCEL);
}
Пример #19
0
// Open Image
ptImage* ptImage::ptGMCOpenImage(const char*        FileName,
                                 short              ColorSpace,
                                 short              Intent,
                                 short              ScaleFactor,
                                 bool               IsRAW,
                                 TImage8RawData*    ImgData,
                                 bool&              Success)
{
  Success = 0;

  MagickWand* image = NewMagickWand();
  ExceptionType MagickExcept;

  if (IsRAW) {
    MagickReadImageBlob(image, (const uchar*)ImgData->data(), (const size_t)ImgData->size());
  } else {
    if (!QFile::exists(QString::fromLocal8Bit(FileName))) return this;
    MagickReadImage(image, FileName);
  }

  MagickGetException(image, &MagickExcept);
  if (MagickExcept != UndefinedException) {
    return this;
  }

  Success = 1;

  // Get the embedded profile
  cmsHPROFILE InProfile = NULL;

  if (MagickGetImageType(image) != GrayscaleType) {
    ulong ProfileLength = 0;
    uchar* IccProfile = MagickGetImageProfile(image, "ICC", &ProfileLength);

    if (ProfileLength > 0) {
      InProfile = cmsOpenProfileFromMem(IccProfile, ProfileLength);
    }
  }
  if (!InProfile) {
    InProfile = cmsCreate_sRGBProfile();
  }

  MagickSetImageType(image, TrueColorType);
  MagickSetImageFormat(image, "RGB");
  MagickSetImageDepth(image, 16);

  uint16_t NewWidth = MagickGetImageWidth(image);
  uint16_t NewHeight = MagickGetImageHeight(image);

  // Buffer for the data from Magick
  std::vector<std::array<float, 3> > ImageBuffer;
  ImageBuffer.resize((size_t) NewWidth*NewHeight);

  MagickGetImagePixels(image, 0, 0, NewWidth, NewHeight, "RGB", FloatPixel, (uchar*)ImageBuffer.data());

  m_Width = NewWidth;
  DestroyMagickWand(image);

  // Image before color transform, may be binned
  std::vector<std::array<float, 3> > NewImage;

  if (ScaleFactor != 0) {
    // Binning
    NewHeight >>= ScaleFactor;
    NewWidth >>= ScaleFactor;

    short Step = 1 << ScaleFactor;
    int Average = pow(2,2 * ScaleFactor);

    NewImage.resize((size_t)NewWidth*NewHeight);

#pragma omp parallel for schedule(static)
    for (uint16_t Row=0; Row < NewHeight*Step; Row+=Step) {
      for (uint16_t Col=0; Col < NewWidth*Step; Col+=Step) {
        float  PixelValue[3] = {0.0f,0.0f,0.0f};
        for (uint8_t sRow=0; sRow < Step; sRow++) {
          for (uint8_t sCol=0; sCol < Step; sCol++) {
            int32_t index = (Row+sRow)*m_Width+Col+sCol;
            for (short c=0; c < 3; c++) {
              PixelValue[c] += ImageBuffer[index][c];
            }
          }
        }
        for (short c=0; c < 3; c++) {
          NewImage[Row/Step*NewWidth+Col/Step][c]
            = PixelValue[c] / Average;
        }
      }
    }
  } else {
Пример #20
0
void Color::LoadICCProfiles()
{
	if(m_iccSearchPaths!= NULL){
		delete m_iccSearchPaths;
	}
    
    const Int32 NUMSEARCHPATHS = 4;
    
	m_iccSearchPaths = new String[NUMSEARCHPATHS];
	

	Filename cmykDir = GeGetPluginPath();
	cmykDir += Filename(String("cmyk"));

	m_iccSearchPaths[0] = cmykDir.GetString();
    m_iccSearchPaths[1] = "/Library/ColorSync/Profiles/";
    m_iccSearchPaths[2] = "/Users/vidarn/Library/ColorSync";
	m_iccSearchPaths[3] = "C:\\Windows\\System32\\Spool\\Drivers\\Color\\";

	Logger::AddLine("Creating LAB profile",1);
	m_LABProfile = cmsCreateLab4Profile(NULL);

	Logger::AddLine("Creating default sRGB profile",1);
	m_displayProfile = cmsCreate_sRGBProfile();
	m_RGBProfiles.Insert(vnColorProfile("sRGB",m_displayProfile),0);

    for(Int32 i=0;i<NUMSEARCHPATHS;++i){
        BrowseFiles* bf = BrowseFiles::Alloc();
        Filename dir(m_iccSearchPaths[i]);
        bf->Init(dir,FALSE);
        int RGBPos  = m_RGBProfiles.GetCount();
        int CMYKPos = m_CMYKProfiles.GetCount();
        int spotPos = m_spotProfiles.GetCount();

        if (bf)
        {
            while (bf->GetNext())
            {
                Filename fileName = bf->GetFilename();
                fileName.SetDirectory(dir);
                String str = fileName.GetString();
                Char *buffer = new Char[str.GetCStringLen()+1];
                str.GetCString(buffer,str.GetCStringLen()+1);
				Logger::AddLine(buffer,1);
                cmsHPROFILE profile = cmsOpenProfileFromFile(buffer, "r");
                if(profile != NULL){
                    cmsColorSpaceSignature sig = cmsGetColorSpace(profile);
                    Int32 length = cmsGetProfileInfoASCII(profile,cmsInfoDescription,"en","US",NULL,0);
                    Char *buffer2 = new Char[length];
                    cmsGetProfileInfoASCII(profile,cmsInfoDescription,"en","US",buffer2,length);
                    String info(buffer2);
                    int pt = _cmsLCMScolorSpace(sig);
                    if(PT_RGB == pt){
						Logger::AddLine("RGB profile",1);
                        m_RGBProfiles.Insert(vnColorProfile(info,profile),RGBPos);
                        RGBPos++;
                    }
                    if(PT_CMYK == pt){
                        cmsHTRANSFORM xform = cmsCreateTransform(profile,TYPE_NAMED_COLOR_INDEX,m_displayProfile,TYPE_RGB_DBL,INTENT_PERCEPTUAL,0);
                        if(xform != NULL){
                            cmsNAMEDCOLORLIST* colorList = cmsGetNamedColorList(xform);
                            if(colorList != NULL){
                                m_spotProfiles.Insert(vnColorProfile(info,profile),spotPos);
                                spotPos++;
                            }
                            else{
								Logger::AddLine("CMYK profile",1);
                                m_CMYKProfiles.Insert(vnColorProfile(info,profile),CMYKPos);
                                CMYKPos++;
                            }
							cmsDeleteTransform(xform);
                        }
                    }
                    delete buffer2;
                } else {
					Logger::AddLine("Invalid",1);
				}
                delete buffer;
            }
        }
        BrowseFiles::Free(bf);
    }
}
Пример #21
0
void color_apply_icc_profile(opj_image_t* image) {
  cmsHPROFILE out_prof;
  cmsUInt32Number in_type;
  cmsUInt32Number out_type;
  int* r;
  int* g;
  int* b;
  int max;
  cmsHPROFILE in_prof =
      cmsOpenProfileFromMem(image->icc_profile_buf, image->icc_profile_len);
  if (!in_prof) {
    return;
  }
  cmsColorSpaceSignature out_space = cmsGetColorSpace(in_prof);
  cmsUInt32Number intent = cmsGetHeaderRenderingIntent(in_prof);
  int max_w = (int)image->comps[0].w;
  int max_h = (int)image->comps[0].h;
  int prec = (int)image->comps[0].prec;
  OPJ_COLOR_SPACE oldspace = image->color_space;
  if (out_space == cmsSigRgbData) {
    if (prec <= 8) {
      in_type = TYPE_RGB_8;
      out_type = TYPE_RGB_8;
    } else {
      in_type = TYPE_RGB_16;
      out_type = TYPE_RGB_16;
    }
    out_prof = cmsCreate_sRGBProfile();
    image->color_space = OPJ_CLRSPC_SRGB;
  } else if (out_space == cmsSigGrayData) {
    if (prec <= 8) {
      in_type = TYPE_GRAY_8;
      out_type = TYPE_RGB_8;
    } else {
      in_type = TYPE_GRAY_16;
      out_type = TYPE_RGB_16;
    }
    out_prof = cmsCreate_sRGBProfile();
    image->color_space = OPJ_CLRSPC_SRGB;
  } else if (out_space == cmsSigYCbCrData) {
    in_type = TYPE_YCbCr_16;
    out_type = TYPE_RGB_16;
    out_prof = cmsCreate_sRGBProfile();
    image->color_space = OPJ_CLRSPC_SRGB;
  } else {
    return;
  }
  cmsHTRANSFORM transform =
      cmsCreateTransform(in_prof, in_type, out_prof, out_type, intent, 0);
  cmsCloseProfile(in_prof);
  cmsCloseProfile(out_prof);
  if (!transform) {
    image->color_space = oldspace;
    return;
  }
  if (image->numcomps > 2) {
    if (prec <= 8) {
      unsigned char *inbuf, *outbuf, *in, *out;
      max = max_w * max_h;
      cmsUInt32Number nr_samples = max * 3 * sizeof(unsigned char);
      in = inbuf = FX_Alloc(unsigned char, nr_samples);
      out = outbuf = FX_Alloc(unsigned char, nr_samples);
      r = image->comps[0].data;
      g = image->comps[1].data;
      b = image->comps[2].data;
      for (int i = 0; i < max; ++i) {
        *in++ = (unsigned char)*r++;
        *in++ = (unsigned char)*g++;
        *in++ = (unsigned char)*b++;
      }
      cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
      r = image->comps[0].data;
      g = image->comps[1].data;
      b = image->comps[2].data;
      for (int i = 0; i < max; ++i) {
        *r++ = (int)*out++;
        *g++ = (int)*out++;
        *b++ = (int)*out++;
      }
      FX_Free(inbuf);
      FX_Free(outbuf);
    } else {
Пример #22
0
PyObject *
load_png_fast_progressive (char *filename,
                           PyObject *get_buffer_callback)
{
  // Note: we are not using the method that libpng calls "Reading PNG
  // files progressively". That method would involve feeding the data
  // into libpng piece by piece, which is not necessary if we can give
  // libpng a simple FILE pointer.

  png_structp png_ptr = NULL;
  png_infop info_ptr = NULL;
  PyObject * result = NULL;
  FILE *fp = NULL;
  uint32_t width, height;
  uint32_t rows_left;
  png_byte color_type;
  png_byte bit_depth;
  bool have_alpha;
  char *cm_processing = NULL;

  // ICC profile-based colour conversion data.
  png_charp icc_profile_name = NULL;
  int icc_compression_type = 0;
#if PNG_LIBPNG_VER < 10500    // 1.5.0beta36, according to libpng CHANGES
  png_charp icc_profile = NULL;
#else
  png_bytep icc_profile = NULL;
#endif
  png_uint_32 icc_proflen = 0;

  // The sRGB flag has an intent field, which we ignore - 
  // the target gamut is sRGB already.
  int srgb_intent = 0;

  // Generic RGB space conversion params.
  // The assumptions we're making are those of sRGB,
  // but they'll be overridden by gammas or primaries in the file if used.
  bool generic_rgb_have_gAMA = false;
  bool generic_rgb_have_cHRM = false;
  double generic_rgb_file_gamma = 45455 / PNG_gAMA_scale;
  double generic_rgb_white_x = 31270 / PNG_cHRM_scale;
  double generic_rgb_white_y = 32900 / PNG_cHRM_scale;
  double generic_rgb_red_x   = 64000 / PNG_cHRM_scale;
  double generic_rgb_red_y   = 33000 / PNG_cHRM_scale;
  double generic_rgb_green_x = 30000 / PNG_cHRM_scale;
  double generic_rgb_green_y = 60000 / PNG_cHRM_scale;
  double generic_rgb_blue_x  = 15000 / PNG_cHRM_scale;
  double generic_rgb_blue_y  =  6000 / PNG_cHRM_scale;

  // Indicates the case where no CM information was present in the file and we
  // treated it as sRGB.
  bool possible_legacy_png = false;

  // LCMS stuff
  cmsHPROFILE input_buffer_profile = NULL;
  cmsHPROFILE nparray_data_profile = cmsCreate_sRGBProfile();
  cmsHTRANSFORM input_buffer_to_nparray = NULL;
  cmsToneCurve *gamma_transfer_func = NULL;
  cmsUInt32Number input_buffer_format = 0;

  cmsSetLogErrorHandler(log_lcms2_error);

  fp = fopen(filename, "rb");
  if (!fp) {
    PyErr_SetFromErrno(PyExc_IOError);
    //PyErr_Format(PyExc_IOError, "Could not open PNG file for writing: %s",
    //             filename);
    goto cleanup;
  }

  png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
                                    png_read_error_callback, NULL);
  if (!png_ptr) {
    PyErr_SetString(PyExc_MemoryError, "png_create_write_struct() failed");
    goto cleanup;
  }

  info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr) {
    PyErr_SetString(PyExc_MemoryError, "png_create_info_struct() failed");
    goto cleanup;
  }

  if (setjmp(png_jmpbuf(png_ptr))) {
    goto cleanup;
  }

  png_init_io(png_ptr, fp);

  png_read_info(png_ptr, info_ptr);

  // If there's an embedded ICC profile, use it in preference to any other
  // colour management information present.
  if (png_get_iCCP (png_ptr, info_ptr, &icc_profile_name,
                    &icc_compression_type, &icc_profile,
                    &icc_proflen))
  {
    input_buffer_profile = cmsOpenProfileFromMem(icc_profile, icc_proflen);
    if (! input_buffer_profile) {
      PyErr_SetString(PyExc_MemoryError, "cmsOpenProfileFromMem() failed");
      goto cleanup;
    }
    cm_processing = "iCCP (use embedded colour profile)";
  }

  // Shorthand for sRGB.
  else if (png_get_sRGB (png_ptr, info_ptr, &srgb_intent)) {
    input_buffer_profile = cmsCreate_sRGBProfile();
    cm_processing = "sRGB (explicit sRGB chunk)";
  }

  else {
    // We might have generic RGB transformation information in the form of
    // the chromaticities for R, G and B and a generic gamma curve.

    if (png_get_cHRM (png_ptr, info_ptr,
                      &generic_rgb_white_x, &generic_rgb_white_y,
                      &generic_rgb_red_x, &generic_rgb_red_y,
                      &generic_rgb_green_x, &generic_rgb_green_y,
                      &generic_rgb_blue_x, &generic_rgb_blue_y))
    {
      generic_rgb_have_cHRM = true;
    }
    if (png_get_gAMA(png_ptr, info_ptr, &generic_rgb_file_gamma)) {
      generic_rgb_have_gAMA = true;
    }
    if (generic_rgb_have_gAMA || generic_rgb_have_cHRM) {
      cmsCIExyYTRIPLE primaries = {{generic_rgb_red_x, generic_rgb_red_y},
                                   {generic_rgb_green_x, generic_rgb_green_y},
                                   {generic_rgb_blue_x, generic_rgb_blue_y}};
      cmsCIExyY white_point = {generic_rgb_white_x, generic_rgb_white_y};
      gamma_transfer_func = cmsBuildGamma(NULL, 1.0/generic_rgb_file_gamma);
      cmsToneCurve *transfer_funcs[3] = {gamma_transfer_func,
                                         gamma_transfer_func,
                                         gamma_transfer_func };
      input_buffer_profile = cmsCreateRGBProfile(&white_point, &primaries,
                                                transfer_funcs);
      cm_processing = "cHRM and/or gAMA (generic RGB space)";
    }

    // Possible legacy PNG, or rather one which might have been written with an
    // old version of MyPaint. Treat as sRGB, but flag the strangeness because
    // it might be important for PNGs in old OpenRaster files.
    else {
      possible_legacy_png = true;
      input_buffer_profile = cmsCreate_sRGBProfile();
      cm_processing = "sRGB (no CM chunks present)";
    }
  }

  if (png_get_interlace_type (png_ptr, info_ptr) != PNG_INTERLACE_NONE) {
    PyErr_SetString(PyExc_RuntimeError,
                    "Interlaced PNG files are not supported!");
    goto cleanup;
  }

  color_type = png_get_color_type(png_ptr, info_ptr);
  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
  have_alpha = color_type & PNG_COLOR_MASK_ALPHA;

  if (color_type == PNG_COLOR_TYPE_PALETTE) {
    png_set_palette_to_rgb(png_ptr);
  }

  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
    png_set_expand_gray_1_2_4_to_8(png_ptr);
  }

  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
    png_set_tRNS_to_alpha(png_ptr);
    have_alpha = true;
  }

  if (bit_depth < 8) {
    png_set_packing(png_ptr);
  }

  if (!have_alpha) {
    png_set_add_alpha(png_ptr, 0xFF, PNG_FILLER_AFTER);
  }

  if (color_type == PNG_COLOR_TYPE_GRAY ||
      color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
    png_set_gray_to_rgb(png_ptr);
  }

  png_read_update_info(png_ptr, info_ptr);

  // Verify what we have done
  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
  if (! (bit_depth == 8 || bit_depth == 16)) {
    PyErr_SetString(PyExc_RuntimeError, "Failed to convince libpng to convert "
                                        "to 8 or 16 bits per channel");
    goto cleanup;
  }
  if (png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_RGB_ALPHA) {
    PyErr_SetString(PyExc_RuntimeError, "Failed to convince libpng to convert "
                                        "to RGBA (wrong color_type)");
    goto cleanup;
  }
  if (png_get_channels(png_ptr, info_ptr) != 4) {
    PyErr_SetString(PyExc_RuntimeError, "Failed to convince libpng to convert "
                                        "to RGBA (wrong number of channels)");
    goto cleanup;
  }

  // PNGs use network byte order, i.e. big-endian in descending order
  // of bit significance. LittleCMS uses whatever's detected for the compiler.
  // ref: http://www.w3.org/TR/2003/REC-PNG-20031110/#7Integers-and-byte-order
  if (bit_depth == 16) {
#ifdef CMS_USE_BIG_ENDIAN
    input_buffer_format = TYPE_RGBA_16;
#else
    input_buffer_format = TYPE_RGBA_16_SE;
#endif
  }
  else {
    input_buffer_format = TYPE_RGBA_8;
  }

  input_buffer_to_nparray = cmsCreateTransform
        (input_buffer_profile, input_buffer_format,
         nparray_data_profile, TYPE_RGBA_8,
         INTENT_PERCEPTUAL, 0);

  width = png_get_image_width(png_ptr, info_ptr);
  height = png_get_image_height(png_ptr, info_ptr);
  rows_left = height;

  while (rows_left) {
    PyObject *pyarr = NULL;
    uint32_t rows = 0;
    uint32_t row = 0;
    const uint8_t input_buf_bytes_per_pixel = (bit_depth==8) ? 4 : 8;
    const uint32_t input_buf_row_stride = sizeof(png_byte) * width
                                          * input_buf_bytes_per_pixel;
    png_byte *input_buffer = NULL;
    png_bytep *input_buf_row_pointers = NULL;

    pyarr = PyObject_CallFunction(get_buffer_callback, "ii", width, height);
    if (! pyarr) {
      PyErr_Format(PyExc_RuntimeError, "Get-buffer callback failed");
      goto cleanup;
    }
#ifdef HEAVY_DEBUG
    //assert(PyArray_ISCARRAY(arr));
    assert(PyArray_NDIM(pyarr) == 3);
    assert(PyArray_DIM(pyarr, 1) == width);
    assert(PyArray_DIM(pyarr, 2) == 4);
    assert(PyArray_TYPE(pyarr) == NPY_UINT8);
    assert(PyArray_ISBEHAVED(pyarr));
    assert(PyArray_STRIDE(pyarr, 1) == 4*sizeof(uint8_t));
    assert(PyArray_STRIDE(pyarr, 2) ==   sizeof(uint8_t));
#endif
    rows = PyArray_DIM(pyarr, 0);

    if (rows > rows_left) {
      PyErr_Format(PyExc_RuntimeError,
                   "Attempt to read %d rows from the PNG, "
                   "but only %d are left",
                   rows, rows_left);
      goto cleanup;
    }

    input_buffer = (png_byte *) malloc(rows * input_buf_row_stride);
    input_buf_row_pointers = (png_bytep *)malloc(rows * sizeof(png_bytep));
    for (row=0; row<rows; row++) {
      input_buf_row_pointers[row] = input_buffer + (row * input_buf_row_stride);
    }

    png_read_rows(png_ptr, input_buf_row_pointers, NULL, rows);
    rows_left -= rows;

    for (row=0; row<rows; row++) {
      uint8_t *pyarr_row = (uint8_t *)PyArray_DATA(pyarr)
                         + row*PyArray_STRIDE(pyarr, 0);
      uint8_t *input_row = input_buf_row_pointers[row];
      // Really minimal fake colour management. Just remaps to sRGB.
      cmsDoTransform(input_buffer_to_nparray, input_row, pyarr_row, width);
      // lcms2 ignores alpha, so copy that verbatim
      // If it's 8bpc RGBA, use A.
      // If it's 16bpc RrGgBbAa, use A.
      for (uint32_t i=0; i<width; ++i) {
        const uint32_t pyarr_alpha_byte = (i*4) + 3;
        const uint32_t buf_alpha_byte = (i*input_buf_bytes_per_pixel)
                                       + ((bit_depth==8) ? 3 : 6);
        pyarr_row[pyarr_alpha_byte] = input_row[buf_alpha_byte];
      }
    }

    free(input_buf_row_pointers);
    free(input_buffer);

    Py_DECREF(pyarr);
  }

  png_read_end(png_ptr, NULL);

  result = Py_BuildValue("{s:b,s:i,s:i,s:s}",
                         "possible_legacy_png", possible_legacy_png,
                         "width", width,
                         "height", height,
                         "cm_conversions_applied", cm_processing);

 cleanup:
  if (info_ptr) png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
  // libpng's style is to free internally allocated stuff like the icc
  // tables in png_destroy_*(). I think.
  if (fp) fclose(fp);
  if (input_buffer_profile) cmsCloseProfile(input_buffer_profile);
  if (nparray_data_profile) cmsCloseProfile(nparray_data_profile);
  if (input_buffer_to_nparray) cmsDeleteTransform(input_buffer_to_nparray);
  if (gamma_transfer_func) cmsFreeToneCurve(gamma_transfer_func);

  return result;
}
Пример #23
0
    bool write(const pfs::Frame &frame, const JpegWriterParams& params,
               const std::string& filename)
    {
        cmsUInt32Number cmsProfileSize = 0;
        utils::ScopedCmsProfile hsRGB( cmsCreate_sRGBProfile() );

        cmsSaveProfileToMem(hsRGB.data(), NULL, &cmsProfileSize);           // get the size

        std::vector<JOCTET> cmsOutputProfile(cmsProfileSize);

        cmsSaveProfileToMem(hsRGB.data(), cmsOutputProfile.data(), &cmsProfileSize);

        struct jpeg_compress_struct cinfo;
        struct jpeg_error_mgr errorHandler;

        jpeg_create_compress(&cinfo);

        cinfo.err                        = jpeg_std_error(&errorHandler);
        errorHandler.error_exit          = my_writer_error_handler;
        errorHandler.output_message      = my_writer_output_message;

        cinfo.image_width           = frame.getWidth();                 // image width and height, in pixels
        cinfo.image_height          = frame.getHeight();
        cinfo.input_components      = cinfo.num_components = 3;         // # of color components per pixel
        cinfo.in_color_space        = JCS_RGB;                          // colorspace of input image
        cinfo.jpeg_color_space      = JCS_YCbCr;
        cinfo.density_unit          = 1;                                // dots/inch
        cinfo.X_density             = cinfo.Y_density = 72;

        jpeg_set_defaults(&cinfo);
        jpeg_set_colorspace(&cinfo, JCS_YCbCr);

        // avoid subsampling on high quality factor
        jpeg_set_quality(&cinfo, params.quality_, 1);
        if ( params.quality_ >= 70 ) {
            for (int i = 0; i < cinfo.num_components; i++) {
                cinfo.comp_info[i].h_samp_factor = 1;
                cinfo.comp_info[i].v_samp_factor = 1;
            }
        }

        try
        {
            setupJpegDest(&cinfo, filename);

            jpeg_start_compress(&cinfo, true);

            const Channel* rChannel;
            const Channel* gChannel;
            const Channel* bChannel;
            frame.getXYZChannels(rChannel, gChannel, bChannel);

            write_icc_profile(&cinfo, cmsOutputProfile.data(), cmsProfileSize);

            // If an exception is raised, this buffer gets automatically destructed!
            std::vector<JSAMPLE> scanLineOut(cinfo.image_width * cinfo.num_components);
            JSAMPROW scanLineOutArray[1] = { scanLineOut.data() };

            while (cinfo.next_scanline < cinfo.image_height)
            {
                // copy line from Frame into scanLineOut
                utils::transform(
                            rChannel->row_begin(cinfo.next_scanline),
                            rChannel->row_end(cinfo.next_scanline),
                            gChannel->row_begin(cinfo.next_scanline),
                            bChannel->row_begin(cinfo.next_scanline),
                            FixedStrideIterator<JSAMPLE*, 3>(scanLineOut.data()),
                            FixedStrideIterator<JSAMPLE*, 3>(scanLineOut.data() + 1),
                            FixedStrideIterator<JSAMPLE*, 3>(scanLineOut.data() + 2),
                            utils::chain(
                                colorspace::Normalizer(params.minLuminance_, params.maxLuminance_),
                                utils::CLAMP_F32,
                                Remapper<JSAMPLE>(params.luminanceMapping_)
                                )
                            );
                jpeg_write_scanlines(&cinfo, scanLineOutArray, 1);
            }
        }
        catch (const std::runtime_error& err)
        {
            std::clog << err.what() << std::endl;

            jpeg_destroy_compress(&cinfo);

            return false;
        }

        jpeg_finish_compress(&cinfo);
        jpeg_destroy_compress(&cinfo);

        close();

        return true;
    }
Пример #24
0
Profile::Ptr Profile::getSRgbProfile()
{
    return Profile::Ptr(new Profile(cmsCreate_sRGBProfile()));
}
Пример #25
0
pngquant_error rwpng_read_image24_libpng(FILE *infile, png24_image *mainprog_ptr)
{
    png_structp  png_ptr = NULL;
    png_infop    info_ptr = NULL;
    png_size_t   rowbytes;
    int          color_type, bit_depth;

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr,
      rwpng_error_handler, NULL);
    if (!png_ptr) {
        return PNG_OUT_OF_MEMORY_ERROR;   /* out of memory */
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        return PNG_OUT_OF_MEMORY_ERROR;   /* out of memory */
    }

    /* setjmp() must be called in every function that calls a non-trivial
     * libpng function */

    if (setjmp(mainprog_ptr->jmpbuf)) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return LIBPNG_FATAL_ERROR;   /* fatal libpng error (via longjmp()) */
    }

    struct rwpng_read_data read_data = {infile, 0};
    png_set_read_fn(png_ptr, &read_data, user_read_data);

    png_read_info(png_ptr, info_ptr);  /* read all PNG info up to image data */


    /* alternatively, could make separate calls to png_get_image_width(),
     * etc., but want bit_depth and color_type for later [don't care about
     * compression_type and filter_type => NULLs] */

    png_get_IHDR(png_ptr, info_ptr, &mainprog_ptr->width, &mainprog_ptr->height,
      &bit_depth, &color_type, NULL, NULL, NULL);


    /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
     * transparency chunks to full alpha channel; strip 16-bit-per-sample
     * images to 8 bits per sample; and convert grayscale to RGB[A] */

    /* GRR TO DO:  preserve all safe-to-copy ancillary PNG chunks */

    if (!(color_type & PNG_COLOR_MASK_ALPHA)) {
#ifdef PNG_READ_FILLER_SUPPORTED
        png_set_expand(png_ptr);
        png_set_filler(png_ptr, 65535L, PNG_FILLER_AFTER);
#else
        fprintf(stderr, "pngquant readpng:  image is neither RGBA nor GA\n");
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        mainprog_ptr->retval = 26;
        return mainprog_ptr->retval;
#endif
    }
/*
    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
        png_set_expand(png_ptr);
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
        png_set_expand(png_ptr);
 */
    if (bit_depth == 16)
        png_set_strip_16(png_ptr);

    if (color_type == PNG_COLOR_TYPE_GRAY ||
        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
        png_set_gray_to_rgb(png_ptr);


    /* get and save the gamma info (if any) for writing */

    double gamma;
    mainprog_ptr->gamma = png_get_gAMA(png_ptr, info_ptr, &gamma) ? gamma : 0.45455;

    png_set_interlace_handling(png_ptr);

    /* all transformations have been registered; now update info_ptr data,
     * get rowbytes and channels, and allocate image memory */

    png_read_update_info(png_ptr, info_ptr);

    rowbytes = png_get_rowbytes(png_ptr, info_ptr);

    if ((mainprog_ptr->rgba_data = malloc(rowbytes*mainprog_ptr->height)) == NULL) {
        fprintf(stderr, "pngquant readpng:  unable to allocate image data\n");
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return PNG_OUT_OF_MEMORY_ERROR;
    }

    png_bytepp row_pointers = rwpng_create_row_pointers(info_ptr, png_ptr, mainprog_ptr->rgba_data, mainprog_ptr->height, 0);

    /* now we can go ahead and just read the whole image */

    png_read_image(png_ptr, row_pointers);

    /* and we're done!  (png_read_end() can be omitted if no processing of
     * post-IDAT text/time/etc. is desired) */

    png_read_end(png_ptr, NULL);

#if USE_LCMS
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_iCCP)) {
        png_uint_32 ProfileLen;
        png_bytep ProfileData;
        int  Compression;
        png_charp ProfileName;

        png_get_iCCP(png_ptr, info_ptr, &ProfileName,
                                        &Compression,
                                        &ProfileData,
                                        &ProfileLen);

        cmsHPROFILE hInProfile = cmsOpenProfileFromMem(ProfileData, ProfileLen);
        cmsHPROFILE hOutProfile = cmsCreate_sRGBProfile();

        cmsHTRANSFORM hTransform = cmsCreateTransform(hInProfile, TYPE_RGBA_8,
                                                    hOutProfile, TYPE_RGBA_8,
                                                    INTENT_PERCEPTUAL, 0);

        // suprisingly, using the same input and output works
        cmsDoTransform(hTransform, mainprog_ptr->rgba_data,
                                   mainprog_ptr->rgba_data,
                                   mainprog_ptr->height * mainprog_ptr->width);

        cmsDeleteTransform(hTransform);
        cmsCloseProfile(hOutProfile);
        cmsCloseProfile(hInProfile);
    }
#endif

    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

    mainprog_ptr->file_size = read_data.bytes_read;
    mainprog_ptr->row_pointers = (unsigned char **)row_pointers;

    return SUCCESS;
}
Пример #26
0
cmsHPROFILE dkCmsCreate_sRGBProfile()
{
    return cmsCreate_sRGBProfile();
}
Пример #27
0
/*#define DEBUG_PROFILE*/
void color_apply_icc_profile(opj_image_t *image)
{
	cmsHPROFILE in_prof, out_prof;
	cmsHTRANSFORM transform;
	cmsColorSpaceSignature in_space, out_space;
	cmsUInt32Number intent, in_type, out_type, nr_samples;
	int *r, *g, *b;
	int prec, i, max, max_w, max_h;
	OPJ_COLOR_SPACE oldspace;

	in_prof = 
	 cmsOpenProfileFromMem(image->icc_profile_buf, image->icc_profile_len);
#ifdef DEBUG_PROFILE
  FILE *icm = fopen("debug.icm","wb");
  fwrite( image->icc_profile_buf,1, image->icc_profile_len,icm);
  fclose(icm);
#endif

	if(in_prof == NULL) return;

	in_space = cmsGetPCS(in_prof);
	out_space = cmsGetColorSpace(in_prof);
	intent = cmsGetHeaderRenderingIntent(in_prof);

	
	max_w = (int)image->comps[0].w;
  max_h = (int)image->comps[0].h;
	prec = (int)image->comps[0].prec;
	oldspace = image->color_space;

	if(out_space == cmsSigRgbData) /* enumCS 16 */
   {
  if( prec <= 8 )
{
	in_type = TYPE_RGB_8;
	out_type = TYPE_RGB_8;
}
else
{
	in_type = TYPE_RGB_16;
	out_type = TYPE_RGB_16;
}
	out_prof = cmsCreate_sRGBProfile();
	image->color_space = OPJ_CLRSPC_SRGB;
   }
	else
	if(out_space == cmsSigGrayData) /* enumCS 17 */
   {
	in_type = TYPE_GRAY_8;
	out_type = TYPE_RGB_8;
	out_prof = cmsCreate_sRGBProfile();
	image->color_space = OPJ_CLRSPC_SRGB;
   }
	else
	if(out_space == cmsSigYCbCrData) /* enumCS 18 */
   {
	in_type = TYPE_YCbCr_16;
	out_type = TYPE_RGB_16;
	out_prof = cmsCreate_sRGBProfile();
	image->color_space = OPJ_CLRSPC_SRGB;
   }
	else
   {
#ifdef DEBUG_PROFILE
fprintf(stderr,"%s:%d: color_apply_icc_profile\n\tICC Profile has unknown "
"output colorspace(%#x)(%c%c%c%c)\n\tICC Profile ignored.\n",
__FILE__,__LINE__,out_space,
(out_space>>24) & 0xff,(out_space>>16) & 0xff,
(out_space>>8) & 0xff, out_space & 0xff);
#endif
	return;
   }

#ifdef DEBUG_PROFILE
fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tchannels(%d) prec(%d) w(%d) h(%d)"
"\n\tprofile: in(%p) out(%p)\n",__FILE__,__LINE__,image->numcomps,prec,
max_w,max_h, (void*)in_prof,(void*)out_prof);

fprintf(stderr,"\trender_intent (%u)\n\t"
"color_space: in(%#x)(%c%c%c%c)   out:(%#x)(%c%c%c%c)\n\t"
"       type: in(%u)              out:(%u)\n",
intent,
in_space,
(in_space>>24) & 0xff,(in_space>>16) & 0xff,
(in_space>>8) & 0xff, in_space & 0xff,

out_space,
(out_space>>24) & 0xff,(out_space>>16) & 0xff,
(out_space>>8) & 0xff, out_space & 0xff,

in_type,out_type
 );
#else
  (void)prec;
  (void)in_space;
#endif /* DEBUG_PROFILE */

	transform = cmsCreateTransform(in_prof, in_type,
	 out_prof, out_type, intent, 0);

#ifdef OPJ_HAVE_LIBLCMS2
/* Possible for: LCMS_VERSION >= 2000 :*/
	cmsCloseProfile(in_prof);
	cmsCloseProfile(out_prof);
#endif

	if(transform == NULL)
   {
#ifdef DEBUG_PROFILE
fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tcmsCreateTransform failed. "
"ICC Profile ignored.\n",__FILE__,__LINE__);
#endif
	image->color_space = oldspace;
#ifdef OPJ_HAVE_LIBLCMS1
	cmsCloseProfile(in_prof);
	cmsCloseProfile(out_prof);
#endif
	return;
   }

	if(image->numcomps > 2)/* RGB, RGBA */
   {
  if( prec <= 8 )
{
	unsigned char *inbuf, *outbuf, *in, *out;
	max = max_w * max_h;
  nr_samples = (cmsUInt32Number)max * 3 * (cmsUInt32Number)sizeof(unsigned char);
	in = inbuf = (unsigned char*)malloc(nr_samples);
	out = outbuf = (unsigned char*)malloc(nr_samples);

	r = image->comps[0].data;
	g = image->comps[1].data;
	b = image->comps[2].data;

	for(i = 0; i < max; ++i)
  {
	*in++ = (unsigned char)*r++;
	*in++ = (unsigned char)*g++;
	*in++ = (unsigned char)*b++;
  }

	cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);

	r = image->comps[0].data;
	g = image->comps[1].data;
	b = image->comps[2].data;

	for(i = 0; i < max; ++i)
  {
	*r++ = (int)*out++;
	*g++ = (int)*out++;
	*b++ = (int)*out++;
  }
	free(inbuf); free(outbuf);
}
else
{
	unsigned short *inbuf, *outbuf, *in, *out;
	max = max_w * max_h;
  nr_samples = (cmsUInt32Number)max * 3 * (cmsUInt32Number)sizeof(unsigned short);
	in = inbuf = (unsigned short*)malloc(nr_samples);
	out = outbuf = (unsigned short*)malloc(nr_samples);

	r = image->comps[0].data;
	g = image->comps[1].data;
	b = image->comps[2].data;

	for(i = 0; i < max; ++i)
  {
	*in++ = (unsigned short)*r++;
	*in++ = (unsigned short)*g++;
	*in++ = (unsigned short)*b++;
  }

	cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);

	r = image->comps[0].data;
	g = image->comps[1].data;
	b = image->comps[2].data;

	for(i = 0; i < max; ++i)
  {
	*r++ = (int)*out++;
	*g++ = (int)*out++;
	*b++ = (int)*out++;
  }
	free(inbuf); free(outbuf);
}
   }
	else /* GRAY, GRAYA */
   {
	unsigned char *in, *inbuf, *out, *outbuf;
  max = max_w * max_h;
  nr_samples = (cmsUInt32Number)max * 3 * sizeof(unsigned char);
	in = inbuf = (unsigned char*)malloc(nr_samples);
	out = outbuf = (unsigned char*)malloc(nr_samples);

	image->comps = (opj_image_comp_t*)
	 realloc(image->comps, (image->numcomps+2)*sizeof(opj_image_comp_t));

	if(image->numcomps == 2)
	 image->comps[3] = image->comps[1];

	image->comps[1] = image->comps[0];
	image->comps[2] = image->comps[0];

	image->comps[1].data = (int*)calloc((size_t)max, sizeof(int));
	image->comps[2].data = (int*)calloc((size_t)max, sizeof(int));

	image->numcomps += 2;

	r = image->comps[0].data;

	for(i = 0; i < max; ++i)
  {
	*in++ = (unsigned char)*r++;
  }
	cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);

	r = image->comps[0].data;
	g = image->comps[1].data;
	b = image->comps[2].data;

	for(i = 0; i < max; ++i)
  {
	*r++ = (int)*out++; *g++ = (int)*out++; *b++ = (int)*out++;
  }
	free(inbuf); free(outbuf);

   }/* if(image->numcomps */

	cmsDeleteTransform(transform);

#ifdef OPJ_HAVE_LIBLCMS1
	cmsCloseProfile(in_prof);
	cmsCloseProfile(out_prof);
#endif
}/* color_apply_icc_profile() */
Пример #28
0
void SPImage::apply_profile(Inkscape::Pixbuf *pixbuf) {

    // TODO: this will prevent using MIME data when exporting.
    // Integrate color correction into loading.
    pixbuf->ensurePixelFormat(Inkscape::Pixbuf::PF_GDK);
    int imagewidth = pixbuf->width();
    int imageheight = pixbuf->height();
    int rowstride = pixbuf->rowstride();;
    guchar* px = pixbuf->pixels();

    if ( px ) {
        DEBUG_MESSAGE( lcmsFive, "in <image>'s sp_image_update. About to call colorprofile_get_handle()" );

        guint profIntent = Inkscape::RENDERING_INTENT_UNKNOWN;
        cmsHPROFILE prof = Inkscape::CMSSystem::getHandle( this->document,
                                                           &profIntent,
                                                           this->color_profile );
        if ( prof ) {
            cmsProfileClassSignature profileClass = cmsGetDeviceClass( prof );
            if ( profileClass != cmsSigNamedColorClass ) {
                int intent = INTENT_PERCEPTUAL;
                                
                switch ( profIntent ) {
                    case Inkscape::RENDERING_INTENT_RELATIVE_COLORIMETRIC:
                        intent = INTENT_RELATIVE_COLORIMETRIC;
                        break;
                    case Inkscape::RENDERING_INTENT_SATURATION:
                        intent = INTENT_SATURATION;
                        break;
                    case Inkscape::RENDERING_INTENT_ABSOLUTE_COLORIMETRIC:
                        intent = INTENT_ABSOLUTE_COLORIMETRIC;
                        break;
                    case Inkscape::RENDERING_INTENT_PERCEPTUAL:
                    case Inkscape::RENDERING_INTENT_UNKNOWN:
                    case Inkscape::RENDERING_INTENT_AUTO:
                    default:
                        intent = INTENT_PERCEPTUAL;
                }
                                
                cmsHPROFILE destProf = cmsCreate_sRGBProfile();
                cmsHTRANSFORM transf = cmsCreateTransform( prof,
                                                           TYPE_RGBA_8,
                                                           destProf,
                                                           TYPE_RGBA_8,
                                                           intent, 0 );
                if ( transf ) {
                    guchar* currLine = px;
                    for ( int y = 0; y < imageheight; y++ ) {
                        // Since the types are the same size, we can do the transformation in-place
                        cmsDoTransform( transf, currLine, currLine, imagewidth );
                        currLine += rowstride;
                    }

                    cmsDeleteTransform( transf );
                } else {
                    DEBUG_MESSAGE( lcmsSix, "in <image>'s sp_image_update. Unable to create LCMS transform." );
                }

                cmsCloseProfile( destProf );
            } else {
                DEBUG_MESSAGE( lcmsSeven, "in <image>'s sp_image_update. Profile type is named color. Can't transform." );
            }
        } else {
            DEBUG_MESSAGE( lcmsEight, "in <image>'s sp_image_update. No profile found." );
        }
    }
}
Пример #29
0
void CLASS apply_profile (const char *input, const char *output)
{
  char *prof;
  cmsHPROFILE hInProfile=0, hOutProfile=0;
  cmsHTRANSFORM hTransform;
  FILE *fp;
  unsigned size;

#ifndef USE_LCMS2
  cmsErrorAction (LCMS_ERROR_SHOW);
#endif
  if (strcmp (input, "embed"))
    hInProfile = cmsOpenProfileFromFile (input, "r");
  else if (profile_length) {
#ifndef LIBRAW_LIBRARY_BUILD
    prof = (char *) malloc (profile_length);
    merror (prof, "apply_profile()");
    fseek (ifp, profile_offset, SEEK_SET);
    fread (prof, 1, profile_length, ifp);
    hInProfile = cmsOpenProfileFromMem (prof, profile_length);
    free (prof);
#else
    hInProfile = cmsOpenProfileFromMem (imgdata.color.profile, profile_length);
#endif
  } else
    {
#ifdef LIBRAW_LIBRARY_BUILD
          imgdata.process_warnings |= LIBRAW_WARN_NO_EMBEDDED_PROFILE;
#endif
#ifdef DCRAW_VERBOSE
          fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
#endif
    }
  if (!hInProfile)
      {
#ifdef LIBRAW_LIBRARY_BUILD
          imgdata.process_warnings |= LIBRAW_WARN_NO_INPUT_PROFILE;
#endif
          return;
      }
  if (!output)
    hOutProfile = cmsCreate_sRGBProfile();
  else if ((fp = fopen (output, "rb"))) {
    fread (&size, 4, 1, fp);
    fseek (fp, 0, SEEK_SET);
    oprof = (unsigned *) malloc (size = ntohl(size));
    merror (oprof, "apply_profile()");
    fread (oprof, 1, size, fp);
    fclose (fp);
    if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) {
      free (oprof);
      oprof = 0;
    }
  }
#ifdef DCRAW_VERBOSE
 else
    fprintf (stderr,_("Cannot open file %s!\n"), output);
#endif
  if (!hOutProfile)
      {
#ifdef LIBRAW_LIBRARY_BUILD
          imgdata.process_warnings |= LIBRAW_WARN_BAD_OUTPUT_PROFILE;
#endif
          goto quit;
      }
#ifdef DCRAW_VERBOSE
  if (verbose)
    fprintf (stderr,_("Applying color profile...\n"));
#endif
#ifdef LIBRAW_LIBRARY_BUILD
  RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE,0,2);
#endif
  hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
	hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
  cmsDoTransform (hTransform, image, image, width*height);
  raw_color = 1;		/* Don't use rgb_cam with a profile */
  cmsDeleteTransform (hTransform);
  cmsCloseProfile (hOutProfile);
quit:
  cmsCloseProfile (hInProfile);
#ifdef LIBRAW_LIBRARY_BUILD
  RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE,1,2);
#endif
}
Пример #30
0
static void
cdisplay_lcms_changed (GimpColorDisplay *display)
{
  CdisplayLcms    *lcms   = CDISPLAY_LCMS (display);
  GimpColorConfig *config = gimp_color_display_get_config (display);

  cmsHPROFILE      src_profile   = NULL;
  cmsHPROFILE      dest_profile  = NULL;
  cmsHPROFILE      proof_profile = NULL;
  cmsUInt32Number  flags         = 0;
  cmsUInt16Number  alarmCodes[cmsMAXCHANNELS] = { 0, };

  if (lcms->transform)
    {
      cmsDeleteTransform (lcms->transform);
      lcms->transform = NULL;
    }

  if (! config)
    return;

  switch (config->mode)
    {
    case GIMP_COLOR_MANAGEMENT_OFF:
      return;

    case GIMP_COLOR_MANAGEMENT_SOFTPROOF:
      proof_profile = cdisplay_lcms_get_printer_profile (lcms);
      /*  fallthru  */

    case GIMP_COLOR_MANAGEMENT_DISPLAY:
      src_profile = cdisplay_lcms_get_rgb_profile (lcms);
      dest_profile = cdisplay_lcms_get_display_profile (lcms);
      break;
    }

  if (config->display_intent ==
      GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC)
    {
      flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
    }

  if (proof_profile)
    {
      if (! src_profile)
        src_profile = cmsCreate_sRGBProfile ();

      if (! dest_profile)
        dest_profile = cmsCreate_sRGBProfile ();

      flags |= cmsFLAGS_SOFTPROOFING;

      if (config->simulation_gamut_check)
        {
          guchar r, g, b;

          flags |= cmsFLAGS_GAMUTCHECK;

          gimp_rgb_get_uchar (&config->out_of_gamut_color, &r, &g, &b);

          alarmCodes[0] = (cmsUInt16Number) r * 256;
          alarmCodes[1] = (cmsUInt16Number) g * 256;
          alarmCodes[2] = (cmsUInt16Number) b * 256;

          cmsSetAlarmCodes (alarmCodes);
        }

      lcms->transform = cmsCreateProofingTransform (src_profile, TYPE_ARGB_8,
                                                    dest_profile, TYPE_ARGB_8,
                                                    proof_profile,
                                                    config->simulation_intent,
                                                    config->display_intent,
                                                    flags);
      cmsCloseProfile (proof_profile);
    }
  else if (src_profile || dest_profile)
    {
      if (! src_profile)
        src_profile = cmsCreate_sRGBProfile ();

      if (! dest_profile)
        dest_profile = cmsCreate_sRGBProfile ();

      lcms->transform = cmsCreateTransform (src_profile, TYPE_ARGB_8,
                                            dest_profile, TYPE_ARGB_8,
                                            config->display_intent,
                                            flags);
    }

  if (dest_profile)
    cmsCloseProfile (dest_profile);

  if (src_profile)
    cmsCloseProfile (src_profile);
}