~ubuntu-branches/ubuntu/saucy/digikam/saucy

« back to all changes in this revision

Viewing changes to libs/dimg/filters/icc/iccprofile.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2010-12-21 23:19:11 UTC
  • mfrom: (1.2.33 upstream) (3.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20101221231911-z9jip7s5aht1jqn9
Tags: 2:1.7.0-1ubuntu1
* Merge from Debian Experimental. Remaining Ubuntu changes:
  - Export .pot name and copy to plugins in debian/rules
  - Version build-depends on kipi-plugins-dev to ensure build is against the
    same version on all archs
* Drop debian/patches/kubuntu_01_linker.diff, incoporated upstream
* Remove patches directory and unused patches

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
{
54
54
public:
55
55
 
56
 
    IccProfilePriv()
 
56
    IccProfilePriv() :
 
57
        type(IccProfile::InvalidType),
 
58
        handle(0)
57
59
    {
58
 
        handle      = 0;
59
 
        type        = IccProfile::InvalidType;
60
60
    }
61
61
 
62
62
    IccProfilePriv(const IccProfilePriv& other)
63
 
                : QSharedData(other)
 
63
        : QSharedData(other)
64
64
    {
65
65
        handle      = 0;
66
66
        operator=(other);
67
67
    }
68
68
 
69
 
    IccProfilePriv &operator=(const IccProfilePriv& other)
 
69
    IccProfilePriv& operator=(const IccProfilePriv& other)
70
70
    {
71
71
        data        = other.data;
72
72
        filePath    = other.filePath;
133
133
// ----------------------------------------------------------------------------------
134
134
 
135
135
IccProfile::IccProfile()
136
 
          : d(0)
 
136
    : d(0)
137
137
{
138
138
}
139
139
 
140
140
IccProfile::IccProfile(const QByteArray& data)
141
 
          : d(new IccProfilePriv)
 
141
    : d(new IccProfilePriv)
142
142
{
143
143
    d->data = data;
144
144
}
145
145
 
146
146
IccProfile::IccProfile(const QString& filePath)
147
 
          : d(new IccProfilePriv)
 
147
    : d(new IccProfilePriv)
148
148
{
149
149
    d->filePath = filePath;
150
150
}
151
151
 
152
 
IccProfile::IccProfile(const char *location, const QString& relativePath)
153
 
          : d(0)
 
152
IccProfile::IccProfile(const char* location, const QString& relativePath)
 
153
    : d(0)
154
154
{
155
155
    QString filePath = KStandardDirs::locate(location, relativePath);
 
156
 
156
157
    if (filePath.isNull())
157
158
    {
158
159
        kError() << "The bundled profile" << relativePath << "cannot be found. Check your installation.";
159
160
        return;
160
161
    }
 
162
 
161
163
    d = new IccProfilePriv;
162
164
    d->filePath = filePath;
163
165
}
171
173
IccProfile IccProfile::adobeRGB()
172
174
{
173
175
    QString path = static_d->adobeRGBPath;
 
176
 
174
177
    if (path.isEmpty())
 
178
    {
175
179
        path = KStandardDirs::locate("data", "libkdcraw/profiles/compatibleWithAdobeRGB1998.icc");
 
180
    }
176
181
 
177
182
    if (path.isEmpty()) // this one has a wrong whitepoint. Remove when sufficiently recent libkdcraw is a digikam dependency.
 
183
    {
178
184
        path = KStandardDirs::locate("data", "libkdcraw/profiles/adobergb.icm");
 
185
    }
179
186
 
180
187
    return IccProfile(path);
181
188
}
208
215
}
209
216
 
210
217
IccProfile::IccProfile(const IccProfile& other)
211
 
          : d(other.d)
 
218
    : d(other.d)
212
219
{
213
220
}
214
221
 
216
223
{
217
224
}
218
225
 
219
 
IccProfile &IccProfile::operator=(const IccProfile& other)
 
226
IccProfile& IccProfile::operator=(const IccProfile& other)
220
227
{
221
228
    d = other.d;
222
229
    return *this;
230
237
bool IccProfile::operator==(const IccProfile& other) const
231
238
{
232
239
    if (d == other.d)
 
240
    {
233
241
        return true;
 
242
    }
234
243
 
235
244
    if (d && other.d)
236
245
    {
237
246
        if (!d->filePath.isNull() || !other.d->filePath.isNull())
 
247
        {
238
248
            return d->filePath == other.d->filePath;
 
249
        }
 
250
 
239
251
        if (!d->data.isNull() || other.d->data.isNull())
 
252
        {
240
253
            return d->data == other.d->data;
 
254
        }
241
255
    }
 
256
 
242
257
    return false;
243
258
}
244
259
 
245
260
bool IccProfile::isSameProfileAs(IccProfile& other)
246
261
{
247
262
    if (d == other.d)
 
263
    {
248
264
        return true;
 
265
    }
249
266
 
250
267
    if (d && other.d)
251
268
    {
252
269
        // uses memcmp
253
270
        return data() == other.data();
254
271
    }
 
272
 
255
273
    return false;
256
274
}
257
275
 
258
276
QByteArray IccProfile::data()
259
277
{
260
278
    if (!d)
 
279
    {
261
280
        return QByteArray();
 
281
    }
262
282
 
263
283
    if (!d->data.isEmpty())
264
284
    {
267
287
    else if (!d->filePath.isNull())
268
288
    {
269
289
        QFile file(d->filePath);
 
290
 
270
291
        if ( !file.open(QIODevice::ReadOnly) )
 
292
        {
271
293
            return QByteArray();
 
294
        }
 
295
 
272
296
        d->data = file.readAll();
273
297
        file.close();
274
298
        return d->data;
275
299
    }
 
300
 
276
301
    return QByteArray();
277
302
}
278
303
 
279
304
bool IccProfile::open()
280
305
{
281
306
    if (!d)
 
307
    {
282
308
        return false;
 
309
    }
283
310
 
284
311
    if (d->handle)
 
312
    {
285
313
        return true;
 
314
    }
286
315
 
287
316
    if (!d->data.isEmpty())
288
317
    {
295
324
        data();
296
325
 
297
326
        if (d->data.isEmpty())
 
327
        {
298
328
            return false;
 
329
        }
299
330
 
300
331
        LcmsLock lock;
301
332
        d->handle = cmsOpenProfileFromMem(d->data.data(), (DWORD)d->data.size());
307
338
void IccProfile::close()
308
339
{
309
340
    if (!d)
 
341
    {
310
342
        return;
 
343
    }
311
344
 
312
345
    d->close();
313
346
}
315
348
bool IccProfile::isOpen() const
316
349
{
317
350
    if (!d)
 
351
    {
318
352
        return false;
 
353
    }
319
354
 
320
355
    return d->handle;
321
356
}
323
358
QString IccProfile::filePath() const
324
359
{
325
360
    if (!d)
 
361
    {
326
362
        return QString();
 
363
    }
327
364
 
328
365
    return d->filePath;
329
366
}
331
368
QString IccProfile::description()
332
369
{
333
370
    if (!d)
 
371
    {
334
372
        return QString();
 
373
    }
335
374
 
336
375
    if (!d->description.isNull())
 
376
    {
337
377
        return d->description;
 
378
    }
338
379
 
339
380
    if (!open())
 
381
    {
340
382
        return QString();
 
383
    }
341
384
 
342
385
    LcmsLock lock;
343
 
    const char *desc = cmsTakeProductDesc(d->handle);
 
386
    const char* desc = cmsTakeProductDesc(d->handle);
344
387
 
345
388
    if (desc && desc[0] != '\0')
 
389
    {
346
390
        d->description = QString::fromLatin1(desc);
 
391
    }
347
392
 
348
393
    return d->description;
349
394
}
351
396
IccProfile::ProfileType IccProfile::type()
352
397
{
353
398
    if (!d)
 
399
    {
354
400
        return InvalidType;
 
401
    }
355
402
 
356
403
    if (d->type != InvalidType)
 
404
    {
357
405
        return d->type;
 
406
    }
358
407
 
359
408
    if (!open())
 
409
    {
360
410
        return InvalidType;
 
411
    }
361
412
 
362
413
    LcmsLock lock;
363
414
 
388
439
        default:
389
440
            break;
390
441
    }
 
442
 
391
443
    return d->type;
392
444
}
393
445
 
394
446
bool IccProfile::writeToFile(const QString& filePath)
395
447
{
396
448
    if (!d)
 
449
    {
397
450
        return false;
 
451
    }
398
452
 
399
453
    QByteArray profile = data();
 
454
 
400
455
    if (!profile.isEmpty())
401
456
    {
402
457
        QFile file(filePath);
 
458
 
403
459
        if ( !file.open(QIODevice::WriteOnly) )
 
460
        {
404
461
            return false;
 
462
        }
405
463
 
406
464
        if (file.write(profile) == -1)
 
465
        {
407
466
            return false;
 
467
        }
408
468
 
409
469
        file.close();
410
470
        return true;
411
471
    }
 
472
 
412
473
    return false;
413
474
}
414
475
 
415
 
void *IccProfile::handle() const
 
476
void* IccProfile::handle() const
416
477
{
417
478
    if (!d)
 
479
    {
418
480
        return 0;
 
481
    }
419
482
 
420
483
    return d->handle;
421
484
}
427
490
 
428
491
    paths << KGlobal::dirs()->findDirs("data", "color/icc");
429
492
 
430
 
    #ifdef Q_WS_WIN
431
 
    //TODO
432
 
    #elif defined (Q_WS_MAC)
433
 
    //TODO
434
 
    #else
435
 
 
436
 
        // XDG data dirs, including /usr/share/color/icc
437
 
        QStringList dataDirs = QString::fromLocal8Bit(getenv("XDG_DATA_DIRS")).split(':', QString::SkipEmptyParts);
438
 
 
439
 
        if (!dataDirs.contains(QLatin1String("/usr/share")))
440
 
            dataDirs << "/usr/share";
441
 
 
442
 
        if (!dataDirs.contains(QLatin1String("/usr/local/share")))
443
 
            dataDirs << "/usr/local/share";
444
 
 
445
 
        foreach (const QString& dataDir, dataDirs)
446
 
        {
447
 
            candidates << dataDir + "/color/icc";
448
 
        }
449
 
 
450
 
        // XDG_DATA_HOME
451
 
        QString dataHomeDir = QString::fromLocal8Bit(getenv("XDG_DATA_HOME"));
452
 
        if (!dataHomeDir.isEmpty())
453
 
        {
454
 
            candidates << dataHomeDir + "/color/icc";
455
 
            candidates << dataHomeDir + "/icc";
456
 
        }
457
 
 
458
 
        // home dir directories
459
 
        candidates << QDir::homePath() + "/.local/share/color/icc/";
460
 
        candidates << QDir::homePath() + "/.local/share/icc/";
461
 
        candidates << QDir::homePath() + "/.color/icc/";
462
 
 
463
 
    #endif
 
493
#ifdef Q_WS_WIN
 
494
    //TODO
 
495
#elif defined (Q_WS_MAC)
 
496
    //TODO
 
497
#else
 
498
 
 
499
    // XDG data dirs, including /usr/share/color/icc
 
500
    QStringList dataDirs = QString::fromLocal8Bit(getenv("XDG_DATA_DIRS")).split(':', QString::SkipEmptyParts);
 
501
 
 
502
    if (!dataDirs.contains(QLatin1String("/usr/share")))
 
503
    {
 
504
        dataDirs << "/usr/share";
 
505
    }
 
506
 
 
507
    if (!dataDirs.contains(QLatin1String("/usr/local/share")))
 
508
    {
 
509
        dataDirs << "/usr/local/share";
 
510
    }
 
511
 
 
512
    foreach (const QString& dataDir, dataDirs)
 
513
    {
 
514
        candidates << dataDir + "/color/icc";
 
515
    }
 
516
 
 
517
    // XDG_DATA_HOME
 
518
    QString dataHomeDir = QString::fromLocal8Bit(getenv("XDG_DATA_HOME"));
 
519
 
 
520
    if (!dataHomeDir.isEmpty())
 
521
    {
 
522
        candidates << dataHomeDir + "/color/icc";
 
523
        candidates << dataHomeDir + "/icc";
 
524
    }
 
525
 
 
526
    // home dir directories
 
527
    candidates << QDir::homePath() + "/.local/share/color/icc/";
 
528
    candidates << QDir::homePath() + "/.local/share/icc/";
 
529
    candidates << QDir::homePath() + "/.color/icc/";
 
530
 
 
531
#endif
464
532
 
465
533
    foreach (const QString& candidate, candidates)
466
534
    {
467
535
        QDir dir(candidate);
 
536
 
468
537
        if (dir.exists() && dir.isReadable())
469
538
        {
470
539
            QString path = dir.canonicalPath();
 
540
 
471
541
            if (!paths.contains(path))
 
542
            {
472
543
                paths << path;
 
544
            }
473
545
        }
474
546
    }
475
547
    //kDebug() << candidates << '\n' << paths;
480
552
void IccProfile::considerOriginalAdobeRGB(const QString& filePath)
481
553
{
482
554
    if (!static_d->adobeRGBPath.isNull())
 
555
    {
483
556
        return;
 
557
    }
484
558
 
485
559
    QFile file(filePath);
 
560
 
486
561
    if (file.open(QIODevice::ReadOnly))
487
562
    {
488
563
        KMD5 md5;
489
564
        md5.update(file);
 
565
 
490
566
        if (md5.hexDigest() == "dea88382d899d5f6e573b432473ae138")
491
567
        {
492
568
            kDebug() << "The original Adobe RGB (1998) profile has been found at" << filePath;