[fbreader] Handle data: scheme for XHTML images

This commit is contained in:
Slava Monich 2020-02-04 19:58:48 +02:00
parent 902569313a
commit 9c6ad2d862

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com> * Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com>
* Copyright (C) 2016-2019 Slava Monich <slava.monich@jolla.com> * Copyright (C) 2016-2020 Slava Monich <slava.monich@jolla.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -27,6 +27,7 @@
#include <ZLStringUtil.h> #include <ZLStringUtil.h>
#include <ZLXMLNamespace.h> #include <ZLXMLNamespace.h>
#include <ZLTextStyleCollection.h> #include <ZLTextStyleCollection.h>
#include <ZLBase64EncodedImage.h>
#include "XHTMLReader.h" #include "XHTMLReader.h"
#include "../util/EntityFilesCollector.h" #include "../util/EntityFilesCollector.h"
@ -293,19 +294,45 @@ void XHTMLTagImageAction::doAtStart(XHTMLReader &reader, const char **xmlattribu
return; return;
} }
const std::string fullfileName = pathPrefix(reader) + MiscUtil::decodeHtmlURL(fileName); std::string imageref;
if (!ZLFile(fullfileName).exists()) { shared_ptr<const ZLImage> image;
return;
}
static const char dataSchema[] = { 'd', 'a', 't', 'a', ':' };
if (!strncmp(fileName, dataSchema, sizeof(dataSchema))) {
// data:[<media type>][;base64],<data>
const char* mediaTypeStart = fileName + sizeof(dataSchema);
const char* comma = strchr(mediaTypeStart, ',');
if (comma > mediaTypeStart) {
std::string mediaType(mediaTypeStart, comma - mediaTypeStart);
// Require ";base64" and id
static const std::string base64(";base64");
const char *id = reader.attributeValue(xmlattributes, "id");
if (id && ZLStringUtil::stringEndsWith(mediaType, base64)) {
std::string data(comma + 1);
mediaType.resize(mediaType.length() - base64.length());
ZLBase64EncodedImage* base64img = new ZLBase64EncodedImage(mediaType);
base64img->addData(data, 0, data.length());
image = base64img;
imageref = id;
}
}
} else {
const std::string fullfileName = pathPrefix(reader) + MiscUtil::decodeHtmlURL(fileName);
if (ZLFile(fullfileName).exists()) {
if ((strlen(fileName) > 2) && strncmp(fileName, "./", 2) == 0) { if ((strlen(fileName) > 2) && strncmp(fileName, "./", 2) == 0) {
fileName +=2; fileName +=2;
} }
image = new ZLFileImage(ZLFile(fullfileName), 0);
imageref = fullfileName;
}
}
if (!image.isNull()) {
reader.myParseStack.back().kind = IMAGE; reader.myParseStack.back().kind = IMAGE;
reader.haveContent(); reader.haveContent();
reader.myModelReader.addImageReference(fullfileName); reader.myModelReader.addImageReference(imageref);
reader.myModelReader.addImage(fullfileName, new ZLFileImage(ZLFile(fullfileName), 0)); reader.myModelReader.addImage(imageref, image);
}
} }
XHTMLTagSvgAction::XHTMLTagSvgAction(XHTMLSvgImageAttributeNamePredicate &predicate) : myPredicate(predicate) { XHTMLTagSvgAction::XHTMLTagSvgAction(XHTMLSvgImageAttributeNamePredicate &predicate) : myPredicate(predicate) {