forked from amazingfate/loongoffice
In the document we set the mime type for the images stored, but at import we never actually used the mime types. We always did mime type detection from the filename extension. The problem with this is that files stored as base64 streams don't have a filename so it is also not possible to determine the mime type from the file name. The consequence of this is that we can't know which image to take if we have multiple images (fallback images) so we always take the last one, which could be the wrong one. This happend in the test document. This changes the behavior so that we always first use the document set mime type as there is no reason to not trust that. Only if the mime type isn't provided by the document we use other mime type detection methods. Change-Id: I175c509ce5f11eab2c0454d4d9901ca1fe975272 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160237 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
180 lines
5.6 KiB
C++
180 lines
5.6 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <rtl/ustring.hxx>
|
|
#include <xmlmultiimagehelper.hxx>
|
|
#include <o3tl/string_view.hxx>
|
|
#include <comphelper/graphicmimetype.hxx>
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
namespace
|
|
{
|
|
OUString getMimeTypeForURL(std::u16string_view rString)
|
|
{
|
|
OUString sMimeType;
|
|
if (o3tl::starts_with(rString, u"vnd.sun.star.Package"))
|
|
{
|
|
OString aExtension = OUStringToOString(rString.substr(rString.rfind('.') + 1), RTL_TEXTENCODING_ASCII_US);
|
|
sMimeType = comphelper::GraphicMimeTypeHelper::GetMimeTypeForExtension(aExtension);
|
|
}
|
|
return sMimeType;
|
|
}
|
|
|
|
sal_uInt32 getQualityIndex(std::u16string_view rMimeType)
|
|
{
|
|
// pixel formats first
|
|
if (rMimeType == u"image/bmp")
|
|
{
|
|
return 10;
|
|
}
|
|
if (rMimeType == u"image/gif")
|
|
{
|
|
return 20;
|
|
}
|
|
if (rMimeType == u"image/jpeg")
|
|
{
|
|
return 30;
|
|
}
|
|
if (rMimeType == u"image/png")
|
|
{
|
|
return 40;
|
|
}
|
|
|
|
// vector formats, prefer always
|
|
if (rMimeType == u"image/x-vclgraphic") // MIMETYPE_VCLGRAPHIC
|
|
{
|
|
return 990;
|
|
}
|
|
if (rMimeType == u"image/x-svm")
|
|
{
|
|
return 1000;
|
|
}
|
|
if (rMimeType == u"image/x-wmf")
|
|
{
|
|
return 1010;
|
|
}
|
|
if (rMimeType == u"image/x-emf")
|
|
{
|
|
return 1020;
|
|
}
|
|
if (rMimeType == u"image/x-eps")
|
|
{
|
|
return 1025;
|
|
}
|
|
if (rMimeType == u"application/pdf")
|
|
{
|
|
return 1030;
|
|
}
|
|
if (rMimeType == u"image/svg+xml")
|
|
{
|
|
return 1040;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
MultiImageImportHelper::MultiImageImportHelper()
|
|
: mbSupportsMultipleContents(false)
|
|
{
|
|
}
|
|
|
|
MultiImageImportHelper::~MultiImageImportHelper()
|
|
{
|
|
}
|
|
|
|
SvXMLImportContextRef MultiImageImportHelper::solveMultipleImages()
|
|
{
|
|
SvXMLImportContextRef pContext;
|
|
if(maImplContextVector.size() > 1)
|
|
{
|
|
// multiple child contexts were imported, decide which is the most valuable one
|
|
// and remove the rest
|
|
std::vector<SvXMLImportContextRef>::size_type nIndexOfPreferred(maImplContextVector.size());
|
|
sal_uInt32 nBestQuality(0);
|
|
|
|
for(std::vector<SvXMLImportContextRef>::size_type a = 0; a < maImplContextVector.size(); a++)
|
|
{
|
|
const SvXMLImportContext& rContext = *maImplContextVector[a];
|
|
|
|
// First try the mime type provided by the document
|
|
OUString sMimeType = getMimeTypeFromImportContext(rContext);
|
|
if (sMimeType.isEmpty())
|
|
{
|
|
// Try to determine the mime type from the extension
|
|
const OUString aStreamURL(getGraphicPackageURLFromImportContext(rContext));
|
|
if (!aStreamURL.isEmpty())
|
|
{
|
|
sMimeType = getMimeTypeForURL(aStreamURL);
|
|
}
|
|
else
|
|
{
|
|
// Try to determine the mime type from the graphic itself
|
|
uno::Reference<graphic::XGraphic> xGraphic(getGraphicFromImportContext(rContext));
|
|
if (xGraphic.is())
|
|
sMimeType = comphelper::GraphicMimeTypeHelper::GetMimeTypeForXGraphic(xGraphic);
|
|
}
|
|
}
|
|
|
|
sal_uInt32 nNewQuality = getQualityIndex(sMimeType);
|
|
if (nNewQuality > nBestQuality)
|
|
{
|
|
nBestQuality = nNewQuality;
|
|
nIndexOfPreferred = a;
|
|
}
|
|
}
|
|
|
|
// correct if needed, default is to use the last entry
|
|
if(nIndexOfPreferred >= maImplContextVector.size())
|
|
{
|
|
nIndexOfPreferred = maImplContextVector.size() - 1;
|
|
}
|
|
|
|
// Take out the most valuable one
|
|
const std::vector< SvXMLImportContextRef >::iterator aRemove(maImplContextVector.begin() + nIndexOfPreferred);
|
|
pContext = *aRemove;
|
|
maImplContextVector.erase(aRemove);
|
|
|
|
// remove the rest from parent
|
|
for(std::vector<SvXMLImportContextRef>::size_type a = 0; a < maImplContextVector.size(); a++)
|
|
{
|
|
SvXMLImportContext& rCandidate = *maImplContextVector[a];
|
|
|
|
removeGraphicFromImportContext(rCandidate);
|
|
}
|
|
// re-insert it so that solveMultipleImages is idempotent
|
|
maImplContextVector.clear();
|
|
maImplContextVector.push_back(pContext);
|
|
}
|
|
else if (maImplContextVector.size() == 1)
|
|
{
|
|
pContext = maImplContextVector.front();
|
|
}
|
|
|
|
return pContext;
|
|
}
|
|
|
|
void MultiImageImportHelper::addContent(const SvXMLImportContext& rSvXMLImportContext)
|
|
{
|
|
maImplContextVector.emplace_back(const_cast< SvXMLImportContext* >(&rSvXMLImportContext));
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|