mirror of
https://github.com/YACReader/yacreader
synced 2025-06-04 01:28:55 -04:00
Pdfium isn't threadsafe? Pdfium gets mutexed!
This commit is contained in:
parent
760c1b3847
commit
e935281b47
@ -22,18 +22,30 @@ int pdfRead(void* param,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pdfium is not threadsafe
|
||||||
|
// We need to use mutex locking & refcounting to avoid crashes
|
||||||
|
|
||||||
|
int PdfiumComic::refcount = 0;
|
||||||
|
QMutex PdfiumComic::pdfmutex;
|
||||||
|
|
||||||
PdfiumComic::PdfiumComic()
|
PdfiumComic::PdfiumComic()
|
||||||
{
|
{
|
||||||
FPDF_InitLibrary();
|
QMutexLocker locker(&pdfmutex);
|
||||||
|
if (++refcount == 1) {
|
||||||
|
FPDF_InitLibrary();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PdfiumComic::~PdfiumComic()
|
PdfiumComic::~PdfiumComic()
|
||||||
{
|
{
|
||||||
|
QMutexLocker locker(&pdfmutex);
|
||||||
if (doc)
|
if (doc)
|
||||||
{
|
{
|
||||||
FPDF_CloseDocument(doc);
|
FPDF_CloseDocument(doc);
|
||||||
}
|
}
|
||||||
FPDF_DestroyLibrary();
|
if (--refcount == 0) {
|
||||||
|
FPDF_DestroyLibrary();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PdfiumComic::openComic(const QString & path)
|
bool PdfiumComic::openComic(const QString & path)
|
||||||
@ -50,6 +62,7 @@ bool PdfiumComic::openComic(const QString & path)
|
|||||||
fileAccess.m_GetBlock = pdfRead;
|
fileAccess.m_GetBlock = pdfRead;
|
||||||
fileAccess.m_Param = &pdfFile;
|
fileAccess.m_Param = &pdfFile;
|
||||||
|
|
||||||
|
QMutexLocker lock(&pdfmutex);
|
||||||
doc = FPDF_LoadCustomDocument(&fileAccess, NULL);
|
doc = FPDF_LoadCustomDocument(&fileAccess, NULL);
|
||||||
if (doc)
|
if (doc)
|
||||||
{
|
{
|
||||||
@ -64,13 +77,15 @@ bool PdfiumComic::openComic(const QString & path)
|
|||||||
|
|
||||||
void PdfiumComic::closeComic()
|
void PdfiumComic::closeComic()
|
||||||
{
|
{
|
||||||
FPDF_CloseDocument(doc);
|
QMutexLocker locker(&pdfmutex);
|
||||||
|
FPDF_CloseDocument(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int PdfiumComic::numPages()
|
unsigned int PdfiumComic::numPages()
|
||||||
{
|
{
|
||||||
if (doc)
|
if (doc)
|
||||||
{
|
{
|
||||||
|
QMutexLocker locker(&pdfmutex);
|
||||||
return FPDF_GetPageCount(doc);
|
return FPDF_GetPageCount(doc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -90,26 +105,31 @@ QImage PdfiumComic::getPage(const int page)
|
|||||||
FPDF_PAGE pdfpage;
|
FPDF_PAGE pdfpage;
|
||||||
FPDF_BITMAP bitmap;
|
FPDF_BITMAP bitmap;
|
||||||
|
|
||||||
|
QMutexLocker locker(&pdfmutex);
|
||||||
pdfpage = FPDF_LoadPage(doc, page);
|
pdfpage = FPDF_LoadPage(doc, page);
|
||||||
|
|
||||||
if (!pdfpage)
|
if (!pdfpage)
|
||||||
{
|
{
|
||||||
|
// TODO report error
|
||||||
|
qDebug() << FPDF_GetLastError();
|
||||||
return QImage();
|
return QImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: make target DPI configurable
|
// TODO: make target DPI configurable
|
||||||
double width = (FPDF_GetPageWidth(pdfpage)/72)*150;
|
double width = (FPDF_GetPageWidth(pdfpage)/72)*150;
|
||||||
double height = (FPDF_GetPageHeight(pdfpage)/72)*150;
|
double height = (FPDF_GetPageHeight(pdfpage)/72)*150;
|
||||||
|
|
||||||
image = QImage(width, height, QImage::Format_ARGB32);// QImage::Format_RGBX8888);
|
image = QImage(width, height, QImage::Format_ARGB32);// QImage::Format_RGBX8888);
|
||||||
if (image.isNull())
|
if (image.isNull())
|
||||||
{
|
{
|
||||||
|
// TODO report OOM error
|
||||||
|
qDebug() << "Image too large, OOM";
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
image.fill(0xFFFFFFFF);
|
image.fill(0xFFFFFFFF);
|
||||||
|
|
||||||
bitmap = FPDFBitmap_CreateEx(image.width(), image.height(), FPDFBitmap_BGRA, image.scanLine(0), image.bytesPerLine());
|
bitmap = FPDFBitmap_CreateEx(image.width(), image.height(), FPDFBitmap_BGRA, image.scanLine(0), image.bytesPerLine());
|
||||||
//TODO: make render flags costumizable
|
// TODO: make render flags costumizable
|
||||||
FPDF_RenderPageBitmap(bitmap, pdfpage, 0,0, image.width(), image.height(), 0, (FPDF_LCD_TEXT));
|
FPDF_RenderPageBitmap(bitmap, pdfpage, 0,0, image.width(), image.height(), 0, (FPDF_LCD_TEXT));
|
||||||
FPDFBitmap_Destroy(bitmap);
|
FPDFBitmap_Destroy(bitmap);
|
||||||
FPDF_ClosePage(pdfpage);
|
FPDF_ClosePage(pdfpage);
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
#if defined Q_OS_MAC && defined USE_PDFKIT
|
#if defined Q_OS_MAC && defined USE_PDFKIT
|
||||||
class MacOSXPDFComic
|
class MacOSXPDFComic
|
||||||
@ -16,7 +17,7 @@ class MacOSXPDFComic
|
|||||||
unsigned int numPages();
|
unsigned int numPages();
|
||||||
QImage getPage(const int page);
|
QImage getPage(const int page);
|
||||||
//void releaseLastPageData();
|
//void releaseLastPageData();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void * document;
|
void * document;
|
||||||
void * lastPageData;
|
void * lastPageData;
|
||||||
@ -34,8 +35,10 @@ class PdfiumComic
|
|||||||
void closeComic();
|
void closeComic();
|
||||||
unsigned int numPages();
|
unsigned int numPages();
|
||||||
QImage getPage(const int page);
|
QImage getPage(const int page);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static int refcount;
|
||||||
|
static QMutex pdfmutex;
|
||||||
FPDF_LIBRARY_CONFIG config;
|
FPDF_LIBRARY_CONFIG config;
|
||||||
FPDF_DOCUMENT doc;
|
FPDF_DOCUMENT doc;
|
||||||
FPDF_FILEACCESS fileAccess;
|
FPDF_FILEACCESS fileAccess;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user