diff options
Diffstat (limited to 'src/libs/widgets/iccprofiles/iccprofilewidget.cpp')
-rw-r--r-- | src/libs/widgets/iccprofiles/iccprofilewidget.cpp | 448 |
1 files changed, 448 insertions, 0 deletions
diff --git a/src/libs/widgets/iccprofiles/iccprofilewidget.cpp b/src/libs/widgets/iccprofiles/iccprofilewidget.cpp new file mode 100644 index 00000000..2e5152f7 --- /dev/null +++ b/src/libs/widgets/iccprofiles/iccprofilewidget.cpp @@ -0,0 +1,448 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2006-06-23 + * Description : a tab widget to display ICC profile infos + * + * Copyright (C) 2006-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; + * either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * ============================================================ */ + +#include <config.h> + +// TQt includes. + +#include <tqlayout.h> +#include <tqpushbutton.h> +#include <tqwhatsthis.h> +#include <tqlabel.h> +#include <tqmap.h> +#include <tqhbox.h> +#include <tqfile.h> +#include <tqcombobox.h> +#include <tqgroupbox.h> +#include <tqmap.h> + +// KDE includes. + +#include <kdialogbase.h> +#include <tdelocale.h> +#include <tdeapplication.h> + +// Lcms includes. + +#include LCMS_HEADER +#if LCMS_VERSION < 114 +#define cmsTakeCopyright(profile) "Unknown" +#endif // LCMS_VERSION < 114 + +// Local includes. + +#include "ddebug.h" +#include "metadatalistview.h" +#include "cietonguewidget.h" +#include "iccprofilewidget.h" +#include "iccprofilewidget.moc" + +namespace Digikam +{ + +static const char* ICCHumanList[] = +{ + "ColorSpace", + "Copyright", + "DeviceClass", + "Name", + "Description", + "RenderingIntent", + "-1" +}; + +// This entry list is only require for compatibility with MetadataWidget implementation. +static const char* ICCEntryList[] = +{ + "Header", + "-1" +}; + +class ICCTagInfo +{ + +public: + + ICCTagInfo(){} + + ICCTagInfo(const TQString& title, const TQString& description) + : m_title(title), m_description(description){} + + TQString title() const { return m_title; } + TQString description() const { return m_description; } + +private: + + TQString m_title; + TQString m_description; +}; + +typedef TQMap<TQString, ICCTagInfo> ICCTagInfoMap; + +class ICCProfileWidgetPriv +{ + +public: + + ICCProfileWidgetPriv() + { + cieTongue = 0; + } + + TQStringList tagsfilter; + TQStringList keysFilter; + + CIETongueWidget *cieTongue; + + ICCTagInfoMap iccTagsDescription; +}; + + +ICCProfileWidget::ICCProfileWidget(TQWidget* parent, const char* name, int w, int h) + : MetadataWidget(parent, name) +{ + cmsErrorAction(LCMS_ERROR_SHOW); + + d = new ICCProfileWidgetPriv; + + // Set the translated ICC tags titles/descriptions list + d->iccTagsDescription["Icc.Header.Name"] = ICCTagInfo(i18n("Name"), + i18n("The ICC profile product name")); + d->iccTagsDescription["Icc.Header.Description"] = ICCTagInfo(i18n("Description"), + i18n("The ICC profile product description")); + d->iccTagsDescription["Icc.Header.Information"] = ICCTagInfo(i18n("Information"), + i18n("Additional ICC profile information")); + d->iccTagsDescription["Icc.Header.Manufacturer"] = ICCTagInfo(i18n("Manufacturer"), + i18n("Raw information about the ICC profile manufacturer")); + d->iccTagsDescription["Icc.Header.Model"] = ICCTagInfo(i18n("Model"), + i18n("Raw information about the ICC profile model")); + d->iccTagsDescription["Icc.Header.Copyright"] = ICCTagInfo(i18n("Copyright"), + i18n("Raw information about the ICC profile copyright")); + d->iccTagsDescription["Icc.Header.ProfileID"] = ICCTagInfo(i18n("Profile ID"), + i18n("The ICC profile ID number")); + d->iccTagsDescription["Icc.Header.ColorSpace"] = ICCTagInfo(i18n("Color Space"), + i18n("The color space used by the ICC profile")); + d->iccTagsDescription["Icc.Header.ConnectionSpace"] = ICCTagInfo(i18n("Connection Space"), + i18n("The connection space used by the ICC profile")); + d->iccTagsDescription["Icc.Header.DeviceClass"] = ICCTagInfo(i18n("Device Class"), + i18n("The ICC profile device class")); + d->iccTagsDescription["Icc.Header.RenderingIntent"] = ICCTagInfo(i18n("Rendering Intent"), + i18n("The ICC profile rendering intent")); + d->iccTagsDescription["Icc.Header.ProfileVersion"] = ICCTagInfo(i18n("Profile Version"), + i18n("The ICC version used to record the profile")); + d->iccTagsDescription["Icc.Header.CMMFlags"] = ICCTagInfo(i18n("CMM Flags"), + i18n("The ICC profile color management flags")); + + // Set the list of keys and tags filters. + for (int i=0 ; TQString(ICCEntryList[i]) != TQString("-1") ; i++) + d->keysFilter << ICCEntryList[i]; + + for (int i=0 ; TQString(ICCHumanList[i]) != TQString("-1") ; i++) + d->tagsfilter << ICCHumanList[i]; + + // Add CIE tongue graph to the widget area + + d->cieTongue = new CIETongueWidget(w, h, this); + TQWhatsThis::add( d->cieTongue, i18n("<p>This area contains a CIE or chromaticity diagram. " + "A CIE diagram is a representation of all the colors " + "that a person with normal vision can see. This is represented " + "by the colored sail-shaped area. In addition you will see a " + "triangle that is superimposed on the diagram outlined in white. " + "This triangle represents the outer boundaries of the color space " + "of the device that is characterized by the inspected profile. " + "This is called the device gamut.<p>" + "In addition there are black dots and yellow lines on the diagram. " + "Each black dot represents one of the measurement points that were " + "used to create this profile. The yellow line represents the " + "amount that each point is corrected by the profile, and the " + "direction of this correction.")); + + setUserAreaWidget(d->cieTongue); + decodeMetadata(); +} + +ICCProfileWidget::~ICCProfileWidget() +{ + delete d; +} + +void ICCProfileWidget::setDataLoading() +{ + d->cieTongue->loadingStarted(); +} + +void ICCProfileWidget::setLoadingFailed() +{ + d->cieTongue->loadingFailed(); +} + +TQString ICCProfileWidget::getMetadataTitle() +{ + return i18n("ICC Color Profile Information"); +} + +bool ICCProfileWidget::loadFromURL(const KURL& url) +{ + setFileName(url.path()); + + if (url.isEmpty()) + { + setMetadata(); + d->cieTongue->setProfileData(); + return false; + } + else + { + TQFile file(url.path()); + if ( !file.open(IO_ReadOnly) ) + { + setMetadata(); + d->cieTongue->setProfileData(); + return false; + } + + TQByteArray iccData(file.size()); + TQDataStream stream( &file ); + stream.readRawBytes(iccData.data(), iccData.size()); + file.close(); + + if (iccData.isEmpty()) + { + setMetadata(); + d->cieTongue->setProfileData(); + return false; + } + else + { + setMetadata(iccData); + d->cieTongue->setProfileData(iccData); + } + } + + return true; +} + +bool ICCProfileWidget::decodeMetadata() +{ + TQByteArray iccData = getMetadata(); + if (iccData.isNull()) + return false; + + d->cieTongue->setProfileData(iccData); + + cmsHPROFILE hProfile = cmsOpenProfileFromMem(iccData.data(), (DWORD)iccData.size()); + + if (!hProfile) + { + DDebug() << "Cannot parse ICC profile tags using LCMS" << endl; + return false; + } + + DMetadata::MetaDataMap metaDataMap; + + if ( !TQString(cmsTakeProductName(hProfile)).isEmpty() ) + metaDataMap.insert("Icc.Header.Name", TQString(cmsTakeProductName(hProfile)).replace("\n", " ")); + + if ( !TQString(cmsTakeProductDesc(hProfile)).isEmpty() ) + metaDataMap.insert("Icc.Header.Description", TQString(cmsTakeProductDesc(hProfile)).replace("\n", " ")); + + if ( !TQString(cmsTakeProductInfo(hProfile)).isEmpty() ) + metaDataMap.insert("Icc.Header.Information", TQString(cmsTakeProductInfo(hProfile)).replace("\n", " ")); + + if ( !TQString(cmsTakeManufacturer(hProfile)).isEmpty() ) + metaDataMap.insert("Icc.Header.Manufacturer", TQString(cmsTakeManufacturer(hProfile)).replace("\n", " ")); + + if ( !TQString(cmsTakeModel(hProfile)).isEmpty() ) + metaDataMap.insert("Icc.Header.Model", TQString(cmsTakeModel(hProfile)).replace("\n", " ")); + + if ( !TQString(cmsTakeCopyright(hProfile)).isEmpty() ) + metaDataMap.insert("Icc.Header.Copyright", TQString(cmsTakeCopyright(hProfile)).replace("\n", " ")); + + metaDataMap.insert("Icc.Header.ProfileID", TQString::number((uint)*cmsTakeProfileID(hProfile))); + metaDataMap.insert("Icc.Header.ProfileVersion", TQString::number((uint)cmsGetProfileICCversion(hProfile))); + metaDataMap.insert("Icc.Header.CMMFlags", TQString::number((uint)cmsTakeHeaderFlags(hProfile))); + + TQString colorSpace; + switch (cmsGetColorSpace(hProfile)) + { + case icSigLabData: + colorSpace = i18n("Lab"); + break; + case icSigLuvData: + colorSpace = i18n("Luv"); + break; + case icSigRgbData: + colorSpace = i18n("RGB"); + break; + case icSigGrayData: + colorSpace = i18n("GRAY"); + break; + case icSigHsvData: + colorSpace = i18n("HSV"); + break; + case icSigHlsData: + colorSpace = i18n("HLS"); + break; + case icSigCmykData: + colorSpace = i18n("CMYK"); + break; + case icSigCmyData: + colorSpace= i18n("CMY"); + break; + default: + colorSpace = i18n("Unknown"); + break; + } + metaDataMap.insert("Icc.Header.ColorSpace", colorSpace); + + TQString connectionSpace; + switch (cmsGetPCS(hProfile)) + { + case icSigLabData: + connectionSpace = i18n("Lab"); + break; + case icSigLuvData: + connectionSpace = i18n("Luv"); + break; + case icSigRgbData: + connectionSpace = i18n("RGB"); + break; + case icSigGrayData: + connectionSpace = i18n("GRAY"); + break; + case icSigHsvData: + connectionSpace = i18n("HSV"); + break; + case icSigHlsData: + connectionSpace = i18n("HLS"); + break; + case icSigCmykData: + connectionSpace = i18n("CMYK"); + break; + case icSigCmyData: + connectionSpace= i18n("CMY"); + break; + default: + connectionSpace = i18n("Unknown"); + break; + } + metaDataMap.insert("Icc.Header.ConnectionSpace", connectionSpace); + + TQString device; + switch ((int)cmsGetDeviceClass(hProfile)) + { + case icSigInputClass: + device = i18n("Input device"); + break; + case icSigDisplayClass: + device = i18n("Display device"); + break; + case icSigOutputClass: + device = i18n("Output device"); + break; + case icSigColorSpaceClass: + device = i18n("Color space"); + break; + case icSigLinkClass: + device = i18n("Link device"); + break; + case icSigAbstractClass: + device = i18n("Abstract"); + break; + case icSigNamedColorClass: + device = i18n("Named color"); + break; + default: + device = i18n("Unknown"); + break; + } + metaDataMap.insert("Icc.Header.DeviceClass", device); + + TQString intent; + switch (cmsTakeRenderingIntent(hProfile)) + { + case 0: + intent = i18n("Perceptual"); + break; + case 1: + intent = i18n("Relative Colorimetric"); + break; + case 2: + intent = i18n("Saturation"); + break; + case 3: + intent = i18n("Absolute Colorimetric"); + break; + default: + intent = i18n("Unknown"); + break; + } + metaDataMap.insert("Icc.Header.RenderingIntent", intent); + + cmsCloseProfile(hProfile); + + // Update all metadata contents. + setMetadataMap(metaDataMap); + return true; +} + +void ICCProfileWidget::buildView() +{ + if (getMode() == SIMPLE) + { + setIfdList(getMetadataMap(), d->keysFilter, d->tagsfilter); + } + else + { + setIfdList(getMetadataMap(), d->keysFilter, TQStringList()); + } + + MetadataWidget::buildView(); +} + +TQString ICCProfileWidget::getTagTitle(const TQString& key) +{ + ICCTagInfoMap::Iterator it = d->iccTagsDescription.find(key); + if (it != d->iccTagsDescription.end()) + return(it.data().title()); + + return key.section('.', 2, 2); +} + +void ICCProfileWidget::slotSaveMetadataToFile() +{ + KURL url = saveMetadataToFile(i18n("ICC color profile File to Save"), + TQString("*.icc *.icm|"+i18n("ICC Files (*.icc; *.icm)"))); + storeMetadataToFile(url); +} + +TQString ICCProfileWidget::getTagDescription(const TQString& key) +{ + ICCTagInfoMap::Iterator it = d->iccTagsDescription.find(key); + if (it != d->iccTagsDescription.end()) + return(it.data().description()); + + return key.section('.', 2, 2); +} + +} // namespace Digikam |