diff options
author | Michele Calgaro <michele.calgaro@yahoo.it> | 2024-11-22 18:41:30 +0900 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2024-11-22 20:55:03 +0900 |
commit | 5bed6e4a4c916a97f8fe4d1b07f7eecf4d733b90 (patch) | |
tree | f89cc49efc9ca1d0e1579ecb079ee7e7088ff8c8 /src/libs/widgets/iccprofiles | |
parent | 0bfbf616d9c1fd7abb1bd02732389ab35e5f8771 (diff) | |
download | digikam-5bed6e4a4c916a97f8fe4d1b07f7eecf4d733b90.tar.gz digikam-5bed6e4a4c916a97f8fe4d1b07f7eecf4d733b90.zip |
Rename 'digikam' folder to 'src'
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
(cherry picked from commit ee0d99607c14cb63d3ebdb3a970b508949fa8219)
Diffstat (limited to 'src/libs/widgets/iccprofiles')
-rw-r--r-- | src/libs/widgets/iccprofiles/Makefile.am | 23 | ||||
-rw-r--r-- | src/libs/widgets/iccprofiles/cietonguewidget.cpp | 816 | ||||
-rw-r--r-- | src/libs/widgets/iccprofiles/cietonguewidget.h | 115 | ||||
-rw-r--r-- | src/libs/widgets/iccprofiles/iccpreviewwidget.cpp | 83 | ||||
-rw-r--r-- | src/libs/widgets/iccprofiles/iccpreviewwidget.h | 71 | ||||
-rw-r--r-- | src/libs/widgets/iccprofiles/iccprofilewidget.cpp | 448 | ||||
-rw-r--r-- | src/libs/widgets/iccprofiles/iccprofilewidget.h | 79 |
7 files changed, 1635 insertions, 0 deletions
diff --git a/src/libs/widgets/iccprofiles/Makefile.am b/src/libs/widgets/iccprofiles/Makefile.am new file mode 100644 index 00000000..8888d326 --- /dev/null +++ b/src/libs/widgets/iccprofiles/Makefile.am @@ -0,0 +1,23 @@ +METASOURCES = AUTO + +noinst_LTLIBRARIES = libiccprofileswidgets.la + +libiccprofileswidgets_la_SOURCES = iccprofilewidget.cpp cietonguewidget.cpp iccpreviewwidget.cpp + +libiccprofileswidgets_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_TQT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_TDEIO) -ltdetexteditor + +libiccprofileswidgets_la_LIBADD = $(top_builddir)/src/libs/lprof/liblprof.la + +INCLUDES = -I$(top_srcdir)/src/libs/widgets/metadata \ + -I$(top_srcdir)/src/libs/widgets/common \ + -I$(top_srcdir)/src/libs/lprof \ + -I$(top_srcdir)/src/libs/dimg \ + -I$(top_srcdir)/src/libs/dmetadata \ + -I$(top_srcdir)/src/digikam \ + $(LIBKDCRAW_CFLAGS) \ + $(LIBKEXIV2_CFLAGS) \ + $(all_includes) + +digikaminclude_HEADERS = cietonguewidget.h iccprofilewidget.h iccpreviewwidget.h + +digikamincludedir = $(includedir)/digikam diff --git a/src/libs/widgets/iccprofiles/cietonguewidget.cpp b/src/libs/widgets/iccprofiles/cietonguewidget.cpp new file mode 100644 index 00000000..2ec738b3 --- /dev/null +++ b/src/libs/widgets/iccprofiles/cietonguewidget.cpp @@ -0,0 +1,816 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2006-01-10 + * Description : a widget to display CIE tongue from + * an ICC profile. + * + * Copyright (C) 2006-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * Any source code are inspired from lprof project and + * Copyright (C) 1998-2001 Marti Maria + * + * 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. + * + * ============================================================ */ + +// C++ includes. + +#include <cmath> + +// TQt includes. + +#include <tqimage.h> +#include <tqpainter.h> +#include <tqpixmap.h> +#include <tqfile.h> +#include <tqtimer.h> + +// KDE includes. + +#include <tdelocale.h> + +// Local includes. + +#include "ddebug.h" +#include "lcmsprf.h" +#include "cietonguewidget.h" +#include "cietonguewidget.moc" + +namespace Digikam +{ + + // The following table gives the CIE colour matching functions + // \bar{x}(\lambda), \bar{y}(\lambda), and \bar{z}(\lambda), for + // wavelengths \lambda at 5 nanometre increments from 380 nm through + // 780 nm. This table is used in conjunction with Planck's law for + // the energy spectrum of a black body at a given temperature to plot + // the black body curve on the CIE chart. + + // The following table gives the spectral chromaticity co-ordinates + // x(\lambda) and y(\lambda) for wavelengths in 5 nanometre increments + // from 380 nm through 780 nm. These co-ordinates represent the + // position in the CIE x-y space of pure spectral colours of the given + // wavelength, and thus define the outline of the CIE "tongue" + // diagram. + + static const double spectral_chromaticity[81][3] = + { + { 0.1741, 0.0050 }, // 380 nm + { 0.1740, 0.0050 }, + { 0.1738, 0.0049 }, + { 0.1736, 0.0049 }, + { 0.1733, 0.0048 }, + { 0.1730, 0.0048 }, + { 0.1726, 0.0048 }, + { 0.1721, 0.0048 }, + { 0.1714, 0.0051 }, + { 0.1703, 0.0058 }, + { 0.1689, 0.0069 }, + { 0.1669, 0.0086 }, + { 0.1644, 0.0109 }, + { 0.1611, 0.0138 }, + { 0.1566, 0.0177 }, + { 0.1510, 0.0227 }, + { 0.1440, 0.0297 }, + { 0.1355, 0.0399 }, + { 0.1241, 0.0578 }, + { 0.1096, 0.0868 }, + { 0.0913, 0.1327 }, + { 0.0687, 0.2007 }, + { 0.0454, 0.2950 }, + { 0.0235, 0.4127 }, + { 0.0082, 0.5384 }, + { 0.0039, 0.6548 }, + { 0.0139, 0.7502 }, + { 0.0389, 0.8120 }, + { 0.0743, 0.8338 }, + { 0.1142, 0.8262 }, + { 0.1547, 0.8059 }, + { 0.1929, 0.7816 }, + { 0.2296, 0.7543 }, + { 0.2658, 0.7243 }, + { 0.3016, 0.6923 }, + { 0.3373, 0.6589 }, + { 0.3731, 0.6245 }, + { 0.4087, 0.5896 }, + { 0.4441, 0.5547 }, + { 0.4788, 0.5202 }, + { 0.5125, 0.4866 }, + { 0.5448, 0.4544 }, + { 0.5752, 0.4242 }, + { 0.6029, 0.3965 }, + { 0.6270, 0.3725 }, + { 0.6482, 0.3514 }, + { 0.6658, 0.3340 }, + { 0.6801, 0.3197 }, + { 0.6915, 0.3083 }, + { 0.7006, 0.2993 }, + { 0.7079, 0.2920 }, + { 0.7140, 0.2859 }, + { 0.7190, 0.2809 }, + { 0.7230, 0.2770 }, + { 0.7260, 0.2740 }, + { 0.7283, 0.2717 }, + { 0.7300, 0.2700 }, + { 0.7311, 0.2689 }, + { 0.7320, 0.2680 }, + { 0.7327, 0.2673 }, + { 0.7334, 0.2666 }, + { 0.7340, 0.2660 }, + { 0.7344, 0.2656 }, + { 0.7346, 0.2654 }, + { 0.7347, 0.2653 }, + { 0.7347, 0.2653 }, + { 0.7347, 0.2653 }, + { 0.7347, 0.2653 }, + { 0.7347, 0.2653 }, + { 0.7347, 0.2653 }, + { 0.7347, 0.2653 }, + { 0.7347, 0.2653 }, + { 0.7347, 0.2653 }, + { 0.7347, 0.2653 }, + { 0.7347, 0.2653 }, + { 0.7347, 0.2653 }, + { 0.7347, 0.2653 }, + { 0.7347, 0.2653 }, + { 0.7347, 0.2653 }, + { 0.7347, 0.2653 }, + { 0.7347, 0.2653 } // 780 nm + }; + +class CIETongueWidgetPriv +{ +public: + + CIETongueWidgetPriv() + { + hMonitorProfile = 0; + hXYZProfile = 0; + hXFORM = 0; + + Measurement.Patches = 0; + Measurement.Allowed = 0; + blinkTimer = 0; + pos = 0; + + profileDataAvailable = true; + loadingImageMode = false; + loadingImageSucess = false; + } + + bool profileDataAvailable; + bool loadingImageMode; + bool loadingImageSucess; + + double gridside; + + int xBias; + int yBias; + int pxcols; + int pxrows; + int pos; // Position of animation during loading/calculation. + + TQPainter painter; + TQPixmap pixmap; + TQTimer *blinkTimer; + + cmsHPROFILE hMonitorProfile; + cmsHPROFILE hXYZProfile; + cmsHTRANSFORM hXFORM; + cmsCIExyYTRIPLE Primaries; + cmsCIEXYZ MediaWhite; + + MEASUREMENT Measurement; +}; + +CIETongueWidget::CIETongueWidget(int w, int h, TQWidget *parent, cmsHPROFILE hMonitor) + : TQWidget(parent, 0, TQt::WDestructiveClose) +{ + d = new CIETongueWidgetPriv; + d->blinkTimer = new TQTimer( this ); + setMinimumSize(w, h); + cmsErrorAction(LCMS_ERROR_SHOW); + + if (hMonitor) + d->hMonitorProfile = hMonitor; + else + d->hMonitorProfile = cmsCreate_sRGBProfile(); + + d->hXYZProfile = cmsCreateXYZProfile(); + d->hXFORM = cmsCreateTransform(d->hXYZProfile, TYPE_XYZ_16, + d->hMonitorProfile, TYPE_RGB_8, + INTENT_PERCEPTUAL, 0); + + connect(d->blinkTimer, TQ_SIGNAL(timeout()), + this, TQ_SLOT(slotBlinkTimerDone())); +} + +CIETongueWidget::~CIETongueWidget() +{ + if (d->Measurement.Patches) + free(d->Measurement.Patches); + + if (d->Measurement.Allowed) + free(d->Measurement.Allowed); + + cmsDeleteTransform(d->hXFORM); + cmsCloseProfile(d->hXYZProfile); + cmsCloseProfile(d->hMonitorProfile); + delete d; +} + +int CIETongueWidget::grids(double val) const +{ + return (int) floor(val * d->gridside + 0.5); +} + +bool CIETongueWidget::setProfileData(const TQByteArray &profileData) +{ + if (!profileData.isEmpty()) + { + cmsHPROFILE hProfile = cmsOpenProfileFromMem(const_cast<char*>(profileData.data()), + (DWORD)profileData.size()); + + if (!hProfile) + { + d->profileDataAvailable = false; + d->loadingImageSucess = false; + } + else + { + setProfile(hProfile); + cmsCloseProfile(hProfile); + d->profileDataAvailable = true; + d->loadingImageSucess = true; + } + } + else + { + d->profileDataAvailable = false; + d->loadingImageSucess = false; + } + + d->loadingImageMode = false; + + d->blinkTimer->stop(); + repaint(false); + return (d->profileDataAvailable); +} + +bool CIETongueWidget::setProfileFromFile(const KURL& file) +{ + if (!file.isEmpty() && file.isValid()) + { + cmsHPROFILE hProfile = cmsOpenProfileFromFile(TQFile::encodeName(file.path()), "r"); + + if (!hProfile) + { + d->profileDataAvailable = false; + d->loadingImageSucess = false; + } + else + { + setProfile(hProfile); + cmsCloseProfile(hProfile); + d->profileDataAvailable = true; + d->loadingImageSucess = true; + } + } + else + { + d->profileDataAvailable = false; + d->loadingImageSucess = false; + } + + d->blinkTimer->stop(); + repaint(false); + return (d->profileDataAvailable); +} + +void CIETongueWidget::setProfile(cmsHPROFILE hProfile) +{ + // Get the white point. + + ZeroMemory(&(d->MediaWhite), sizeof(cmsCIEXYZ)); + cmsTakeMediaWhitePoint(&(d->MediaWhite), hProfile); + cmsCIExyY White; + cmsXYZ2xyY(&White, &(d->MediaWhite)); + + // Get the colorant matrix. + + ZeroMemory(&(d->Primaries), sizeof(cmsCIExyYTRIPLE)); + + if (cmsIsTag(hProfile, icSigRedColorantTag) && + cmsIsTag(hProfile, icSigGreenColorantTag) && + cmsIsTag(hProfile, icSigBlueColorantTag)) + { + MAT3 Mat; + + if (cmsReadICCMatrixRGB2XYZ(&Mat, hProfile)) + { + // Undo chromatic adaptation + if (cmsAdaptMatrixFromD50(&Mat, &White)) + { + cmsCIEXYZ tmp; + + tmp.X = Mat.v[0].n[0]; + tmp.Y = Mat.v[1].n[0]; + tmp.Z = Mat.v[2].n[0]; + + // ScaleToWhite(&MediaWhite, &tmp); + cmsXYZ2xyY(&(d->Primaries.Red), &tmp); + + tmp.X = Mat.v[0].n[1]; + tmp.Y = Mat.v[1].n[1]; + tmp.Z = Mat.v[2].n[1]; + // ScaleToWhite(&MediaWhite, &tmp); + cmsXYZ2xyY(&(d->Primaries.Green), &tmp); + + tmp.X = Mat.v[0].n[2]; + tmp.Y = Mat.v[1].n[2]; + tmp.Z = Mat.v[2].n[2]; + // ScaleToWhite(&MediaWhite, &tmp); + cmsXYZ2xyY(&(d->Primaries.Blue), &tmp); + } + } + } + + // Get target data stored in profile + + ZeroMemory(&(d->Measurement), sizeof(MEASUREMENT)); + char* CharTarget; + size_t CharTargetSize; + + if (cmsTakeCharTargetData(hProfile, &CharTarget, &CharTargetSize)) + { + LCMSHANDLE hSheet = cmsxIT8LoadFromMem(CharTarget, CharTargetSize); + if (hSheet != NULL) + { + cmsxPCollLoadFromSheet(&(d->Measurement), hSheet); + cmsxIT8Free(hSheet); + cmsxPCollValidatePatches(&(d->Measurement), PATCH_HAS_XYZ|PATCH_HAS_RGB); + } + } +} + +void CIETongueWidget::mapPoint(int& icx, int& icy, LPcmsCIExyY xyY) +{ + icx = (int) floor((xyY->x * (d->pxcols - 1)) + .5); + icy = (int) floor(((d->pxrows - 1) - xyY->y * (d->pxrows - 1)) + .5); +} + +void CIETongueWidget::biasedLine(int x1, int y1, int x2, int y2) +{ + d->painter.drawLine(x1 + d->xBias, y1, x2 + d->xBias, y2); +} + +void CIETongueWidget::biasedText(int x, int y, TQString Txt) +{ + d->painter.drawText(TQPoint(d->xBias + x, y), Txt); +} + +TQRgb CIETongueWidget::colorByCoord(double x, double y) +{ + // Get xyz components scaled from coordinates + + double cx = ((double) x) / (d->pxcols - 1); + double cy = 1.0 - ((double) y) / (d->pxrows - 1); + double cz = 1.0 - cx - cy; + + // Project xyz to XYZ space. Note that in this + // particular case we are substituting XYZ with xyz + + cmsCIEXYZ XYZ = { cx , cy , cz }; + + WORD XYZW[3]; + BYTE RGB[3]; + + cmsFloat2XYZEncoded(XYZW, &XYZ); + cmsDoTransform(d->hXFORM, XYZW, RGB, 1); + + return tqRgb(RGB[0], RGB[1], RGB[2]); +} + +void CIETongueWidget::outlineTongue() +{ + int lx = 0, ly = 0; + int fx=0, fy=0; + + for (int x = 380; x <= 700; x += 5) + { + int ix = (x - 380) / 5; + + cmsCIExyY p = {spectral_chromaticity[ix][0], + spectral_chromaticity[ix][1], 1}; + + int icx, icy; + mapPoint(icx, icy, &p); + + if (x > 380) + { + biasedLine(lx, ly, icx, icy); + } + else + { + fx = icx; + fy = icy; + } + + lx = icx; + ly = icy; + } + + biasedLine(lx, ly, fx, fy); +} + +void CIETongueWidget::fillTongue() +{ + + TQImage Img = d->pixmap.convertToImage(); + + int x; + + for (int y = 0; y < d->pxrows; y++) + { + int xe = 0; + + // Find horizontal extents of tongue on this line. + + for (x = 0; x < d->pxcols; x++) + { + if ((TQColor) Img.pixel(x + d->xBias, y) != TQt::black) + { + for (xe = d->pxcols - 1; xe >= x; xe--) + { + if ((TQColor) Img.pixel(xe + d->xBias, y) != TQt::black) + { + break; + } + } + + break; + } + } + + if (x < d->pxcols) + { + for ( ; x <= xe; x++) + { + TQRgb Color = colorByCoord(x, y); + Img.setPixel(x + d->xBias, y, Color); + } + } + } + + d->pixmap.convertFromImage(Img, TQPixmap::AvoidDither ); +} + +void CIETongueWidget::drawTongueAxis() +{ + TQFont font; + font.setPointSize(6); + d->painter.setFont(font); + + d->painter.setPen(tqRgb(255, 255, 255)); + + biasedLine(0, 0, 0, d->pxrows - 1); + biasedLine(0, d->pxrows-1, d->pxcols-1, d->pxrows - 1); + + for (int y = 1; y <= 9; y += 1) + { + TQString s; + int xstart = (y * (d->pxcols - 1)) / 10; + int ystart = (y * (d->pxrows - 1)) / 10; + + s.sprintf("0.%d", y); + biasedLine(xstart, d->pxrows - grids(1), xstart, d->pxrows - grids(4)); + biasedText(xstart - grids(11), d->pxrows + grids(15), s); + + s.sprintf("0.%d", 10 - y); + biasedLine(0, ystart, grids(3), ystart); + biasedText(grids(-25), ystart + grids(5), s); + } +} + +void CIETongueWidget::drawTongueGrid() +{ + d->painter.setPen(tqRgb(80, 80, 80)); + + for (int y = 1; y <= 9; y += 1) + { + int xstart = (y * (d->pxcols - 1)) / 10; + int ystart = (y * (d->pxrows - 1)) / 10; + + biasedLine(xstart, grids(4), xstart, d->pxrows - grids(4) - 1); + biasedLine(grids(7), ystart, d->pxcols-1-grids(7), ystart); + } +} + +void CIETongueWidget::drawLabels() +{ + TQFont font; + font.setPointSize(5); + d->painter.setFont(font); + + for (int x = 450; x <= 650; x += (x > 470 && x < 600) ? 5 : 10) + { + TQString wl; + int bx = 0, by = 0, tx, ty; + + if (x < 520) + { + bx = grids(-22); + by = grids(2); + } + else if (x < 535) + { + bx = grids(-8); + by = grids(-6); + } + else + { + bx = grids(4); + } + + int ix = (x - 380) / 5; + + cmsCIExyY p = {spectral_chromaticity[ix][0], + spectral_chromaticity[ix][1], 1}; + + int icx, icy; + mapPoint(icx, icy, &p); + + tx = icx + ((x < 520) ? grids(-2) : ((x >= 535) ? grids(2) : 0)); + ty = icy + ((x < 520) ? 0 : ((x >= 535) ? grids(-1) : grids(-2))); + + d->painter.setPen(tqRgb(255, 255, 255)); + biasedLine(icx, icy, tx, ty); + + TQRgb Color = colorByCoord(icx, icy); + d->painter.setPen(Color); + + wl.sprintf("%d", x); + biasedText(icx+bx, icy+by, wl); + } +} + +void CIETongueWidget::drawSmallElipse(LPcmsCIExyY xyY, BYTE r, BYTE g, BYTE b, int sz) +{ + int icx, icy; + + mapPoint(icx, icy, xyY); + d->painter.setPen(tqRgb(r, g, b)); + d->painter.drawEllipse(icx + d->xBias- sz/2, icy-sz/2, sz, sz); +} + +void CIETongueWidget::drawPatches() +{ + for (int i=0; i < d->Measurement.nPatches; i++) + { + LPPATCH p = d->Measurement.Patches + i; + + if (d->Measurement.Allowed[i]) + { + LPcmsCIEXYZ XYZ = &p ->XYZ; + cmsCIExyY xyY; + cmsXYZ2xyY(&xyY, XYZ); + + drawSmallElipse(&xyY, 0, 0, 0, 4); + + if (p->dwFlags & PATCH_HAS_XYZ_PROOF) + { + if (p->XYZ.Y < 0.03) + continue; + + if (p->XYZProof.Y < 0.03) + continue; + + cmsCIExyY Pt; + cmsXYZ2xyY(&Pt, &p->XYZProof); + int icx1, icx2, icy1, icy2; + + mapPoint(icx1, icy1, &xyY); + mapPoint(icx2, icy2, &Pt); + + if (icx2 < 5 || icy2 < 5 || icx1 < 5 || icy1 < 5) + continue; + + d->painter.setPen(tqRgb(255, 255, 0)); + biasedLine(icx1, icy1, icx2, icy2); + } + } + } +} + +void CIETongueWidget::drawColorantTriangle() +{ + drawSmallElipse(&(d->Primaries.Red), 255, 128, 128, 6); + drawSmallElipse(&(d->Primaries.Green), 128, 255, 128, 6); + drawSmallElipse(&(d->Primaries.Blue), 128, 128, 255, 6); + + int x1, y1, x2, y2, x3, y3; + + mapPoint(x1, y1, &(d->Primaries.Red)); + mapPoint(x2, y2, &(d->Primaries.Green)); + mapPoint(x3, y3, &(d->Primaries.Blue)); + + d->painter.setPen(tqRgb(255, 255, 255)); + + biasedLine(x1, y1, x2, y2); + biasedLine(x2, y2, x3, y3); + biasedLine(x3, y3, x1, y1); +} + +void CIETongueWidget::sweep_sRGB() +{ + int r, g, b; + cmsHPROFILE hXYZ, hsRGB; + + hXYZ = cmsCreateXYZProfile(); + hsRGB = cmsCreate_sRGBProfile(); + + cmsHTRANSFORM xform = cmsCreateTransform(hsRGB, TYPE_RGB_16, hXYZ, TYPE_XYZ_16, + INTENT_ABSOLUTE_COLORIMETRIC, cmsFLAGS_NOTPRECALC); + WORD RGB[3], XYZ[3]; + cmsCIEXYZ xyz, MediaWhite; + cmsCIExyY xyY, WhitePt; + int x1, y1; + + cmsTakeMediaWhitePoint(&MediaWhite, hsRGB); + cmsXYZ2xyY(&WhitePt, &MediaWhite); + + for (r=0; r < 65536; r += 1024) + { + for (g=0; g < 65536; g += 1024) + { + for (b=0; b < 65536; b += 1024) + { + RGB[0] = r; RGB[1] = g; RGB[2] = b; + cmsDoTransform(xform, RGB, XYZ, 1); + cmsXYZEncoded2Float(&xyz, XYZ); + cmsXYZ2xyY(&xyY, &xyz); + mapPoint(x1, y1, &xyY); + d->painter.drawPoint(x1 + d->xBias, y1); + } + } + } + + cmsDeleteTransform(xform); + cmsCloseProfile(hXYZ); + cmsCloseProfile(hsRGB); +} + +void CIETongueWidget::drawWhitePoint() +{ + cmsCIExyY Whitem_pntxyY; + cmsXYZ2xyY(&Whitem_pntxyY, &(d->MediaWhite)); + drawSmallElipse(&Whitem_pntxyY, 255, 255, 255, 8); +} + +void CIETongueWidget::loadingStarted() +{ + d->pos = 0; + d->loadingImageMode = true; + d->loadingImageSucess = false; + repaint(false); + d->blinkTimer->start(200); +} + +void CIETongueWidget::loadingFailed() +{ + d->blinkTimer->stop(); + d->pos = 0; + d->loadingImageMode = false; + d->loadingImageSucess = false; + repaint(false); +} + +void CIETongueWidget::paintEvent(TQPaintEvent*) +{ + d->pixmap = TQPixmap(size()); + d->pixmap.setOptimization(TQPixmap::BestOptim); + + // Widget is disable : drawing grayed frame. + + if ( !isEnabled() ) + { + d->painter.begin(&d->pixmap); + d->painter.fillRect(0, 0, size().width(), size().height(), palette().disabled().background()); + d->painter.setPen(TQPen(palette().disabled().foreground(), 1, TQt::SolidLine)); + d->painter.drawRect(0, 0, width(), height()); + d->painter.end(); + bitBlt(this, 0, 0, &d->pixmap); + return; + } + + // Loading image mode. + + if (d->loadingImageMode && !d->loadingImageSucess) + { + // In first, we draw an animation. + + int asize = 24; + TQPixmap anim(asize, asize); + TQPainter p2; + p2.begin(&anim, this); + p2.fillRect(0, 0, asize, asize, palette().active().background()); + p2.translate(asize/2, asize/2); + + d->pos = (d->pos + 10) % 360; + p2.setPen(TQPen(palette().active().text())); + p2.rotate(d->pos); + for ( int i=0 ; i<12 ; i++ ) + { + p2.drawLine(asize/2-5, 0, asize/2-2, 0); + p2.rotate(30); + } + p2.end(); + + // ... and we render busy text. + + d->painter.begin(&d->pixmap); + d->painter.fillRect(0, 0, size().width(), size().height(), palette().active().background()); + d->painter.drawPixmap(width()/2 - asize /2, asize, anim); + d->painter.setPen(TQPen(palette().active().text(), 1, TQt::SolidLine)); + d->painter.drawRect(0, 0, width(), height()); + d->painter.drawText(0, 0, size().width(), size().height(), TQt::AlignCenter, + i18n("Loading image...")); + + d->painter.end(); + bitBlt(this, 0, 0, &d->pixmap); + return; + } + + // No profile data to show. + + if (!d->profileDataAvailable || (!d->loadingImageMode && !d->loadingImageSucess)) + { + d->painter.begin(&d->pixmap); + d->painter.fillRect(0, 0, size().width(), size().height(), palette().active().background()); + d->painter.setPen(TQPen(palette().active().text(), 1, TQt::SolidLine)); + d->painter.drawRect(0, 0, width(), height()); + d->painter.drawText(0, 0, size().width(), size().height(), TQt::AlignCenter, + i18n("No profile available...")); + + d->painter.end(); + bitBlt(this, 0, 0, &d->pixmap); + return; + } + + // Draw the CIE tongue curve. + + d->pixmap.fill(TQt::black); + d->painter.begin(&d->pixmap); + + int pixcols = d->pixmap.width(); + int pixrows = d->pixmap.height(); + + d->gridside = (TQMIN(pixcols, pixrows)) / 512.0; + d->xBias = grids(32); + d->yBias = grids(20); + d->pxcols = pixcols - d->xBias; + d->pxrows = pixrows - d->yBias; + + d->painter.setBackgroundColor(tqRgb(0, 0, 0)); + d->painter.setPen(tqRgb(255, 255, 255)); + + outlineTongue(); + fillTongue(); + + drawTongueAxis(); + drawLabels(); + drawTongueGrid(); + + if (d->MediaWhite.Y > 0.0) + drawWhitePoint(); + + if (d->Primaries.Red.Y != 0.0) + drawColorantTriangle(); + + if (d->Measurement.Patches && d->Measurement.Allowed) + drawPatches(); + + d->painter.end(); + + bitBlt(this, 0, 0, &d->pixmap); +} + +void CIETongueWidget::slotBlinkTimerDone() +{ + repaint(false); + d->blinkTimer->start( 200 ); +} + +} // namespace Digikam diff --git a/src/libs/widgets/iccprofiles/cietonguewidget.h b/src/libs/widgets/iccprofiles/cietonguewidget.h new file mode 100644 index 00000000..9fc8503d --- /dev/null +++ b/src/libs/widgets/iccprofiles/cietonguewidget.h @@ -0,0 +1,115 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2006-01-10 + * Description : a widget to display CIE tongue from + * an ICC profile. + * + * Copyright (C) 2006-2008 by Gilles Caulier <caulier dot gilles at gmail dot com> + * + * Any source code are inspired from lprof project and + * Copyright (C) 1998-2001 Marti Maria + * + * 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. + * + * ============================================================ */ + +#ifndef CIETONGUEWIDGET_H +#define CIETONGUEWIDGET_H + +#include <config.h> + +// TQt includes. + +#include <tqwidget.h> +#include <tqcolor.h> + +// KDE includes. + +#include <kurl.h> + +// lcms includes. + +#include LCMS_HEADER +#if LCMS_VERSION < 114 +#define cmsTakeCopyright(profile) "Unknown" +#endif // LCMS_VERSION < 114 + +// Local includes. + +#include "digikam_export.h" + +namespace Digikam +{ + +class CIETongueWidgetPriv; + +class DIGIKAM_EXPORT CIETongueWidget : public TQWidget +{ +TQ_OBJECT + + +public: + + CIETongueWidget(int w, int h, TQWidget *parent=0, cmsHPROFILE hMonitor=0); + ~CIETongueWidget(); + + bool setProfileData(const TQByteArray& profileData=TQByteArray()); + bool setProfileFromFile(const KURL& file=KURL()); + + void loadingStarted(); + void loadingFailed(); + +protected: + + int grids(double val) const; + + void outlineTongue(); + void fillTongue(); + void drawTongueAxis(); + void drawTongueGrid(); + void drawLabels(); + + TQRgb colorByCoord(double x, double y); + void drawSmallElipse(LPcmsCIExyY xyY, BYTE r, BYTE g, BYTE b, int sz); + + void paintEvent( TQPaintEvent * ); + +private: + + void drawColorantTriangle(); + void drawWhitePoint(); + void drawPatches(); + + void mapPoint(int& icx, int& icy, LPcmsCIExyY xyY); + void biasedLine(int x1, int y1, int x2, int y2); + void biasedText(int x, int y, TQString Txt); + + void sweep_sRGB(); + + void setProfile(cmsHPROFILE hProfile); + +private slots: + + void slotBlinkTimerDone(); + +private : + + CIETongueWidgetPriv* d; + +}; + +} // namespace Digikam + +#endif /* CIETONGUEWIDGET_H */ diff --git a/src/libs/widgets/iccprofiles/iccpreviewwidget.cpp b/src/libs/widgets/iccprofiles/iccpreviewwidget.cpp new file mode 100644 index 00000000..3398b37f --- /dev/null +++ b/src/libs/widgets/iccprofiles/iccpreviewwidget.cpp @@ -0,0 +1,83 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2006-01-12 + * Description : a widget to display ICC profiles descriptions + * in file dialog preview. + * + * Copyright (C) 2006-2007 by Francisco J. Cruz <fj.cruz@supercable.es> + * + * 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. + * + * ============================================================ */ + +// TQt includes. + +#include <tqfileinfo.h> +#include <tqlayout.h> +#include <tqvgroupbox.h> + +// KDE includes. + +#include <kurl.h> + +// Local includes. + +#include "ddebug.h" +#include "iccprofilewidget.h" +#include "iccpreviewwidget.h" +#include "iccpreviewwidget.moc" + +namespace Digikam +{ + +ICCPreviewWidget::ICCPreviewWidget(TQWidget *parent) + : KPreviewWidgetBase( parent ) +{ + TQVBoxLayout *layout = new TQVBoxLayout( this ); + TQVGroupBox *box = new TQVGroupBox( this ); + box->setInsideMargin(0); + box->setFrameStyle(TQFrame::NoFrame|TQFrame::Plain); + m_iccProfileWidget = new ICCProfileWidget(box); + layout->addWidget( box ); +} + +ICCPreviewWidget::~ICCPreviewWidget() +{ +} + +void ICCPreviewWidget::showPreview( const KURL &url) +{ + clearPreview(); + TQFileInfo fInfo(url.path()); + + if ( url.isLocalFile() && fInfo.isFile() && fInfo.isReadable() ) + { + DDebug() << url << " is a readble local file" << endl; + m_iccProfileWidget->loadFromURL(url); + } + else + { + DDebug() << url << " is not a readable local file" << endl; + } +} + +void ICCPreviewWidget::clearPreview() +{ + m_iccProfileWidget->loadFromURL(KURL()); +} + +} // namespace Digikam + + diff --git a/src/libs/widgets/iccprofiles/iccpreviewwidget.h b/src/libs/widgets/iccprofiles/iccpreviewwidget.h new file mode 100644 index 00000000..89b1f4b5 --- /dev/null +++ b/src/libs/widgets/iccprofiles/iccpreviewwidget.h @@ -0,0 +1,71 @@ +/* ============================================================ + * + * This file is a part of digiKam project + * http://www.digikam.org + * + * Date : 2006-01-12 + * Description : a widget to display ICC profiles descriptions + * in file dialog preview. + * + * Copyright (C) 2006-2007 by Francisco J. Cruz <fj.cruz@supercable.es> + * + * 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. + * + * ============================================================ */ + +#ifndef ICCPREVIEWWIDGET_H +#define ICCPREVIEWWIDGET_H + +// KDE includes. + +#include <kpreviewwidgetbase.h> + +// Local includes. + +#include "digikam_export.h" + +class KURL; + +namespace Digikam +{ + +class ICCProfileWidget; + +class DIGIKAM_EXPORT ICCPreviewWidget : public KPreviewWidgetBase +{ + +TQ_OBJECT + + +public: + + ICCPreviewWidget(TQWidget *parent); + ~ICCPreviewWidget(); + +public slots: + + virtual void showPreview(const KURL &url); + +protected: + + virtual void clearPreview(); + virtual void virtual_hook(int, void*){}; + +private : + + ICCProfileWidget *m_iccProfileWidget; + +}; + +} // namespace Digikam + +#endif /* ICCPREVIEWWIDGET_H */ 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 diff --git a/src/libs/widgets/iccprofiles/iccprofilewidget.h b/src/libs/widgets/iccprofiles/iccprofilewidget.h new file mode 100644 index 00000000..d753f30e --- /dev/null +++ b/src/libs/widgets/iccprofiles/iccprofilewidget.h @@ -0,0 +1,79 @@ +/* ============================================================ + * + * 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. + * + * ============================================================ */ + +#ifndef ICCPROFILEWIDGET_H +#define ICCPROFILEWIDGET_H + +// TQt includes. + +#include <tqwidget.h> +#include <tqstring.h> + +// Local includes. + +#include "metadatawidget.h" +#include "digikam_export.h" + +namespace Digikam +{ + +class ICCProfileWidgetPriv; + +class DIGIKAM_EXPORT ICCProfileWidget : public MetadataWidget +{ + TQ_OBJECT + + +public: + + ICCProfileWidget(TQWidget* parent, const char* name=0, int w=256, int h=256); + ~ICCProfileWidget(); + + bool loadFromURL(const KURL& url); + + TQString getTagDescription(const TQString& key); + TQString getTagTitle(const TQString& key); + + TQString getMetadataTitle(); + + void setLoadingFailed(); + void setDataLoading(); + +protected slots: + + virtual void slotSaveMetadataToFile(); + +private: + + bool decodeMetadata(); + void buildView(); + +private: + + ICCProfileWidgetPriv *d; + +}; + +} // namespace Digikam + +#endif /* ICCPROFILEWIDGET_H */ |