1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
/* ============================================================
*
* This file is a part of digiKam project
* http://www.digikam.org
*
* Date : 2005-06-14
* Description : DImg image loader interface
*
* Copyright (C) 2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
* Copyright (C) 2005-2009 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.
*
* ============================================================ */
// KDE includes.
#include <kstandarddirs.h>
// Local includes.
#include "ddebug.h"
#include "dimgprivate.h"
#include "dmetadata.h"
#include "dimgloaderobserver.h"
#include "dimgloader.h"
namespace Digikam
{
DImgLoader::DImgLoader(DImg* image)
: m_image(image)
{
}
int DImgLoader::granularity(DImgLoaderObserver *observer, int total, float progressSlice)
{
// Splits expect total value into the chunks where checks shall occur
// and combines this with a possible correction factor from observer.
// Progress slice is the part of 100% concerned with the current granularity
// (E.g. in a loop only the values from 10% to 90% are used, then progressSlice is 0.8)
// Current default is 1/20, that is progress info every 5%
int granularity=0;
if (observer)
granularity = (int)(( total / (20 * progressSlice)) / observer->granularity());
return granularity ? granularity : 1;
}
unsigned char*& DImgLoader::imageData()
{
return m_image->m_priv->data;
}
unsigned int& DImgLoader::imageWidth()
{
return m_image->m_priv->width;
}
unsigned int& DImgLoader::imageHeight()
{
return m_image->m_priv->height;
}
bool DImgLoader::imageHasAlpha()
{
return m_image->hasAlpha();
}
bool DImgLoader::imageSixteenBit()
{
return m_image->sixteenBit();
}
int DImgLoader::imageBitsDepth()
{
return m_image->bitsDepth();
}
int DImgLoader::imageBytesDepth()
{
return m_image->bytesDepth();
}
TQMap<int, TQByteArray>& DImgLoader::imageMetaData()
{
return m_image->m_priv->metaData;
}
TQVariant DImgLoader::imageGetAttribute(const TQString& key)
{
return m_image->attribute(key);
}
TQString DImgLoader::imageGetEmbbededText(const TQString& key)
{
return m_image->embeddedText(key);
}
void DImgLoader::imageSetAttribute(const TQString& key, const TQVariant& value)
{
m_image->setAttribute(key, value);
}
TQMap<TQString, TQString>& DImgLoader::imageEmbeddedText()
{
return m_image->m_priv->embeddedText;
}
void DImgLoader::imageSetEmbbededText(const TQString& key, const TQString& text)
{
m_image->setEmbeddedText(key, text);
}
bool DImgLoader::readMetadata(const TQString& filePath, DImg::FORMAT /*ff*/)
{
TQMap<int, TQByteArray>& imageMetadata = imageMetaData();
imageMetadata.clear();
DMetadata metaDataFromFile(filePath);
if (!metaDataFromFile.load(filePath))
return false;
// Do not insert null data into metaData map:
// Even if byte array is null, if there is a key in the map, it will
// be interpreted as "There was data, so write it again to the file".
if (!metaDataFromFile.getComments().isNull())
imageMetadata.insert(DImg::COM, metaDataFromFile.getComments());
if (!metaDataFromFile.getExif().isNull())
imageMetadata.insert(DImg::EXIF, metaDataFromFile.getExif());
if (!metaDataFromFile.getIptc().isNull())
imageMetadata.insert(DImg::IPTC, metaDataFromFile.getIptc());
return true;
}
bool DImgLoader::saveMetadata(const TQString& filePath)
{
DMetadata metaDataToFile(filePath);
metaDataToFile.setComments(m_image->getComments());
metaDataToFile.setExif(m_image->getExif());
metaDataToFile.setIptc(m_image->getIptc());
return metaDataToFile.applyChanges();
}
bool DImgLoader::checkExifWorkingColorSpace()
{
DMetadata metaData;
metaData.setExif(m_image->getExif());
// Check if Exif data contains an ICC color profile.
TQByteArray profile = metaData.getExifTagData("Exif.Image.InterColorProfile");
if (!profile.isNull())
{
DDebug() << "Found an ICC profile in Exif metadata" << endl;
m_image->setICCProfil(profile);
return true;
}
// Else check the Exif color-space tag and use a default profiles available in digiKam.
TDEGlobal::dirs()->addResourceType("profiles", TDEGlobal::dirs()->kde_default("data") + "digikam/profiles");
switch(metaData.getImageColorWorkSpace())
{
case DMetadata::WORKSPACE_SRGB:
{
TQString directory = TDEGlobal::dirs()->findResourceDir("profiles", "srgb-d65.icm");
m_image->getICCProfilFromFile(directory + "srgb-d65.icm");
DDebug() << "Exif color-space tag is sRGB. Using default sRGB ICC profile." << endl;
return true;
break;
}
case DMetadata::WORKSPACE_ADOBERGB:
{
TQString directory = TDEGlobal::dirs()->findResourceDir("profiles", "adobergb.icm");
m_image->getICCProfilFromFile(directory + "adobergb.icm");
DDebug() << "Exif color-space tag is AdobeRGB. Using default AdobeRGB ICC profile." << endl;
return true;
break;
}
default:
break;
}
return false;
}
} // NameSpace Digikam
|