Commit 1fa8408e authored by Matus Uzak's avatar Matus Uzak
Browse files

PPT: Improved access to image names.

* It seems to be normal for MS Office 2003 that the MD4 digest of a BLIP
  (specifies the unique identifier of the pixel data in the BLIP) in blipStore
  and OfficeArtDggContainer DOES NOT match.  This means that we can't locate
  the picture for a Picture Shape in the blipStore b y its MD4 digest.

* Using stream offsets to locate the picture.

* Re-save in MS Office 2007 updates the MD4 digests in OfficeArtDggContainer.
  Tests showed that MD4 digests in blipStore were always up2date.

BUG:247633
parent c89f398f
......@@ -637,7 +637,7 @@ PptToOdp::convert(const QString& inputFile, const QString& to, KoStore::Backend
return KoFilter::FileNotFound;
}
KoFilter::ConversionStatus status = doConversion(storage, storeout);
KoFilter::ConversionStatus status = doConversion(storeout);
if (m_progress_update) {
(m_filter->*m_setProgress)(100);
......@@ -654,11 +654,11 @@ PptToOdp::convert(POLE::Storage& storage, KoStore* storeout)
qDebug() << "Parsing and setup failed.";
return KoFilter::InvalidFormat;
}
return doConversion(storage, storeout);
return doConversion(storeout);
}
KoFilter::ConversionStatus
PptToOdp::doConversion(POLE::Storage& storage, KoStore* storeout)
PptToOdp::doConversion(KoStore* storeout)
{
KoOdfWriteStore odfWriter(storeout);
KoXmlWriter* manifest = odfWriter.manifestWriter(
......@@ -895,17 +895,55 @@ void PptToOdp::defineDefaultGraphicProperties(KoGenStyle& style, KoGenStyles& st
odrawtoodf.defineGraphicProperties(style, ds, styles);
}
template<class T>
void
setRgbUid(const T* a, QByteArray& rgbUid)
{
if (!a) return;
rgbUid = a->rgbUid1 + a->rgbUid2;
}
QString PptToOdp::getPicturePath(const quint32 pib) const
{
bool use_offset = false;
quint32 n = pib - 1;
quint32 offset = 0;
const OfficeArtDggContainer& dgg = p->documentContainer->drawingGroup.OfficeArtDgg;
QByteArray rgbUid = getRgbUid(dgg, n);
QByteArray rgbUid = getRgbUid(dgg, n, offset);
if (!rgbUid.isEmpty()) {
if (pictureNames.contains(rgbUid)) {
return "Pictures/" + pictureNames[rgbUid];
} else {
qDebug() << "UNKNOWN picture reference:" << rgbUid.toHex();
use_offset = true;
rgbUid.clear();
}
}
if (use_offset) {
const OfficeArtBStoreDelay& d = p->pictures.anon1;
foreach (const OfficeArtBStoreContainerFileBlock& block, d.anon1) {
if (block.anon.is<OfficeArtBlip>()) {
if (block.anon.get<OfficeArtBlip>()->streamOffset == offset) {
const OfficeArtBlip* b = block.anon.get<OfficeArtBlip>();
setRgbUid(b->anon.get<MSO::OfficeArtBlipEMF>(), rgbUid);
setRgbUid(b->anon.get<MSO::OfficeArtBlipWMF>(), rgbUid);
setRgbUid(b->anon.get<MSO::OfficeArtBlipPICT>(), rgbUid);
setRgbUid(b->anon.get<MSO::OfficeArtBlipJPEG>(), rgbUid);
setRgbUid(b->anon.get<MSO::OfficeArtBlipPNG>(), rgbUid);
setRgbUid(b->anon.get<MSO::OfficeArtBlipDIB>(), rgbUid);
setRgbUid(b->anon.get<MSO::OfficeArtBlipTIFF>(), rgbUid);
if (!rgbUid.isEmpty()) {
if (pictureNames.contains(rgbUid)) {
qDebug() << "Reusing OfficeArtBlip offset:" << offset;
return "Pictures/" + pictureNames[rgbUid];
}
}
}
}
}
}
return QString();
......
......@@ -242,12 +242,10 @@ private:
* Function that does the actual conversion.
*
* It is shared by the two convert() functions.
* @param input an open OLE container that contains the ppt data.
* @param output an open KoStore to write the odp into.
* @return result code of the conversion.
*/
KoFilter::ConversionStatus doConversion(POLE::Storage& input,
KoStore* output);
KoFilter::ConversionStatus doConversion(KoStore* output);
/**
* TODO:
......
......@@ -22,7 +22,7 @@
#include <iostream>
#include <QtCore/QDebug>
#define DEBUG_PICTURE
//#define DEBUG_PICTURES
// Use anonymous namespace to cover following functions
namespace
......@@ -284,7 +284,7 @@ savePicture(const MSO::OfficeArtBStoreContainerFileBlock& a, KoStore* store)
}
QByteArray
getRgbUid(const MSO::OfficeArtDggContainer& dgg, quint32 pib)
getRgbUid(const MSO::OfficeArtDggContainer& dgg, quint32 pib, quint32& offset)
{
// return 16 byte rgbuid for this given blip id
if (dgg.blipStore) {
......@@ -301,6 +301,7 @@ getRgbUid(const MSO::OfficeArtDggContainer& dgg, quint32 pib)
qDebug() << "foDelay:" << fbse->foDelay;
qDebug() << "embeddeBlip:" << fbse->embeddedBlip;
#endif
offset = fbse->foDelay;
return b->rgfb[pib].anon.get<MSO::OfficeArtFBSE>()->rgbUid;
}
}
......
......@@ -31,12 +31,13 @@ struct PictureReference {
/**
* Save the next picture record in the 'Pictures' stream into the ODF store.
* The parameter @position is used to give the picture a unique name.
* The pictures are saved in the currently opened folder of the ODF store.
* It is customary to switch to the folder 'Pictures' before calling this
*
* The pictures are saved in the currently opened folder of the ODF store. It
* is customary to switch to the folder 'Pictures' before calling this
* function.
* @return The name under which the image is saved or an empty string when
* an error occurred.
*
* @return The name under which the image is saved or an empty string when an
* error occurred.
**/
PictureReference savePicture(POLE::Stream& stream, KoStore* store);
......@@ -44,8 +45,13 @@ PictureReference savePicture(const MSO::OfficeArtBStoreContainerFileBlock& a,
KoStore* store);
/**
* Look in blipStore for the id mapping to this object
* Look in blipStore for the id mapping to this object.
*
* @param dgg container for OfficeArt records that contain document-wide data
* @param pib specifies the BLIP to display in the picture shape
* @param offset into the associated OfficeArtBStoreDelay record
* @return unique identifier of the pixel data in the BLIP
**/
QByteArray getRgbUid(const MSO::OfficeArtDggContainer& dgg, quint32 pib);
QByteArray getRgbUid(const MSO::OfficeArtDggContainer& dgg, quint32 pib, quint32& offset);
#endif
......@@ -684,17 +684,18 @@ KWordGraphicsHandler::createFloatingPictures(KoStore* store, KoXmlWriter* manife
QString KWordGraphicsHandler::getPicturePath(quint32 pib) const
{
int picturePosition = pib - 1;
QByteArray rgbUid = getRgbUid(m_officeArtDggContainer, picturePosition);
QString ret("");
quint32 n = pib - 1;
quint32 offset = 0;
QByteArray rgbUid = getRgbUid(m_officeArtDggContainer, n, offset);
if (rgbUid.length()) {
if (m_picNames.contains(rgbUid)) {
ret = "Pictures/" + m_picNames[rgbUid];
return "Pictures/" + m_picNames[rgbUid];
} else {
qDebug() << "UNKNOWN picture reference!";
}
}
return ret;
return QString();
}
void KWordGraphicsHandler::defineDefaultGraphicStyle(KoGenStyles* styles)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment