IGN:pdfreflow plugin now compiles and works on windows and OSX.

This commit is contained in:
Kovid Goyal 2009-09-25 11:02:15 -06:00
parent 02a02f093f
commit 2ddd37f0d2
11 changed files with 143 additions and 109 deletions

View File

@ -6,7 +6,7 @@ __license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os, socket, struct, subprocess import os, socket, struct, subprocess, glob
from distutils.spawn import find_executable from distutils.spawn import find_executable
from PyQt4 import pyqtconfig from PyQt4 import pyqtconfig
@ -84,6 +84,7 @@ ft_lib_dirs = []
ft_libs = [] ft_libs = []
jpg_libs = [] jpg_libs = []
jpg_lib_dirs = [] jpg_lib_dirs = []
poppler_objs = []
fc_inc = '/usr/include/fontconfig' fc_inc = '/usr/include/fontconfig'
fc_lib = '/usr/lib' fc_lib = '/usr/lib'
podofo_inc = '/usr/include/podofo' podofo_inc = '/usr/include/podofo'
@ -102,7 +103,8 @@ if iswindows:
(r'C:\cygwin\home\kovid\poppler\poppler-build\qt4\src\Release;' (r'C:\cygwin\home\kovid\poppler\poppler-build\qt4\src\Release;'
r'C:\cygwin\home\kovid\poppler\poppler-build\Release')) r'C:\cygwin\home\kovid\poppler\poppler-build\Release'))
popplerqt4_lib_dirs = poppler_lib_dirs popplerqt4_lib_dirs = poppler_lib_dirs
poppler_libs = ['poppler', 'poppler-qt4'] poppler_libs = []
poppler_objs = glob.glob(r'C:\cygwin\home\kovid\poppler\poppler-build\poppler.dir\Release\*.obj')
popplerqt4_libs = poppler_libs + ['QtCore4', 'QtGui4'] popplerqt4_libs = poppler_libs + ['QtCore4', 'QtGui4']
png_inc_dirs = [r'C:\cygwin\home\\kovid\gnuwin32\include'] png_inc_dirs = [r'C:\cygwin\home\\kovid\gnuwin32\include']
png_lib_dirs = [r'C:\cygwin\home\\kovid\gnuwin32\lib'] png_lib_dirs = [r'C:\cygwin\home\\kovid\gnuwin32\lib']
@ -120,14 +122,22 @@ elif isosx:
fc_inc = '/Users/kovid/fontconfig/include/fontconfig' fc_inc = '/Users/kovid/fontconfig/include/fontconfig'
fc_lib = '/Users/kovid/fontconfig/lib' fc_lib = '/Users/kovid/fontconfig/lib'
poppler_inc_dirs = consolidate('POPPLER_INC_DIR', poppler_inc_dirs = consolidate('POPPLER_INC_DIR',
'/Volumes/sw/build/poppler-0.10.7/poppler') '/Volumes/sw/build/poppler-0.12.0/poppler:/Volumes/sw/build/poppler-0.12.0')
popplerqt4_inc_dirs = poppler_inc_dirs + [poppler_inc_dirs[0]+'/qt4'] popplerqt4_inc_dirs = poppler_inc_dirs + [poppler_inc_dirs[0]+'/qt4']
poppler_lib_dirs = consolidate('POPPLER_LIB_DIR', poppler_lib_dirs = consolidate('POPPLER_LIB_DIR',
'/Users/kovid/poppler/lib') '/Volumes/sw/lib')
popplerqt4_lib_dirs = poppler_lib_dirs popplerqt4_lib_dirs = poppler_lib_dirs
poppler_libs = popplerqt4_libs = ['poppler'] poppler_libs = popplerqt4_libs = ['poppler']
podofo_inc = '/usr/local/include/podofo' podofo_inc = '/usr/local/include/podofo'
podofo_lib = '/usr/local/lib' podofo_lib = '/usr/local/lib'
magick_inc_dirs = consolidate('MAGICK_INC',
'/Users/kovid/ImageMagick/include/ImageMagick')
magick_lib_dirs = consolidate('MAGICK_LIB',
'/Users/kovid/ImageMagick/lib')
magick_libs = ['MagickWand', 'MagickCore']
png_inc_dirs = consolidate('PNG_INC_DIR', '/usr/local/include')
png_lib_dirs = consolidate('PNG_LIB_DIR', '/usr/local/lib')
png_libs = ['png']
else: else:
# Include directories # Include directories
poppler_inc_dirs = pkgconfig_include_dirs('poppler', poppler_inc_dirs = pkgconfig_include_dirs('poppler',

View File

@ -16,7 +16,7 @@ from setup.build_environment import fc_inc, fc_lib, \
fc_error, poppler_libs, poppler_lib_dirs, poppler_inc_dirs, podofo_inc, \ fc_error, poppler_libs, poppler_lib_dirs, poppler_inc_dirs, podofo_inc, \
podofo_lib, podofo_error, poppler_error, pyqt, OSX_SDK, NMAKE, \ podofo_lib, podofo_error, poppler_error, pyqt, OSX_SDK, NMAKE, \
leopard_build, QMAKE, msvc, MT, win_inc, win_lib, png_inc_dirs, \ leopard_build, QMAKE, msvc, MT, win_inc, win_lib, png_inc_dirs, \
magick_inc_dirs, magick_lib_dirs, png_lib_dirs, png_libs, \ magick_inc_dirs, magick_lib_dirs, png_lib_dirs, png_libs, poppler_objs, \
magick_error, magick_libs, ft_lib_dirs, ft_libs, jpg_libs, jpg_lib_dirs magick_error, magick_libs, ft_lib_dirs, ft_libs, jpg_libs, jpg_lib_dirs
MT MT
isunix = islinux or isosx isunix = islinux or isosx
@ -39,6 +39,7 @@ class Extension(object):
self.sip_files = self.absolutize(kwargs.get('sip_files', [])) self.sip_files = self.absolutize(kwargs.get('sip_files', []))
self.inc_dirs = self.absolutize(kwargs.get('inc_dirs', [])) self.inc_dirs = self.absolutize(kwargs.get('inc_dirs', []))
self.lib_dirs = self.absolutize(kwargs.get('lib_dirs', [])) self.lib_dirs = self.absolutize(kwargs.get('lib_dirs', []))
self.extra_objs = self.absolutize(kwargs.get('extra_objs', []))
self.error = kwargs.get('error', None) self.error = kwargs.get('error', None)
self.libraries = kwargs.get('libraries', []) self.libraries = kwargs.get('libraries', [])
self.cflags = kwargs.get('cflags', []) self.cflags = kwargs.get('cflags', [])
@ -60,6 +61,7 @@ extensions = [
libraries=poppler_libs+magick_libs+png_libs+ft_libs+jpg_libs+pdfreflow_libs, libraries=poppler_libs+magick_libs+png_libs+ft_libs+jpg_libs+pdfreflow_libs,
lib_dirs=poppler_lib_dirs+magick_lib_dirs+png_lib_dirs+ft_lib_dirs+jpg_lib_dirs, lib_dirs=poppler_lib_dirs+magick_lib_dirs+png_lib_dirs+ft_lib_dirs+jpg_lib_dirs,
inc_dirs=poppler_inc_dirs+magick_inc_dirs+png_inc_dirs, inc_dirs=poppler_inc_dirs+magick_inc_dirs+png_inc_dirs,
extra_objs=poppler_objs,
error=reflow_error, error=reflow_error,
cflags=['-DPNG_SKIP_SETJMP_CHECK'] if islinux else [] cflags=['-DPNG_SKIP_SETJMP_CHECK'] if islinux else []
), ),
@ -148,6 +150,7 @@ if isosx:
x, p = ('x86_64', 'ppc64') if leopard_build else ('i386', 'ppc') x, p = ('x86_64', 'ppc64') if leopard_build else ('i386', 'ppc')
archs = ['-arch', x, '-arch', p, '-isysroot', archs = ['-arch', x, '-arch', p, '-isysroot',
OSX_SDK] OSX_SDK]
cflags.append('-D_OSX')
cflags.extend(archs) cflags.extend(archs)
ldflags.extend(archs) ldflags.extend(archs)
ldflags.extend('-bundle -undefined dynamic_lookup'.split()) ldflags.extend('-bundle -undefined dynamic_lookup'.split())
@ -159,6 +162,9 @@ if iswindows:
cc = cxx = msvc.cc cc = cxx = msvc.cc
cflags = '/c /nologo /Ox /MD /W3 /EHsc /DNDEBUG'.split() cflags = '/c /nologo /Ox /MD /W3 /EHsc /DNDEBUG'.split()
ldflags = '/DLL /nologo /INCREMENTAL:NO'.split() ldflags = '/DLL /nologo /INCREMENTAL:NO'.split()
#cflags = '/c /nologo /Ox /MD /W3 /EHsc /Zi'.split()
#ldflags = '/DLL /nologo /INCREMENTAL:NO /DEBUG'.split()
for p in win_inc: for p in win_inc:
cflags.append('-I'+p) cflags.append('-I'+p)
for p in win_lib: for p in win_lib:
@ -268,9 +274,9 @@ class Build(Command):
cmd = [linker] cmd = [linker]
if iswindows: if iswindows:
cmd += ldflags + ext.ldflags + elib + xlib + \ cmd += ldflags + ext.ldflags + elib + xlib + \
['/EXPORT:init'+ext.name] + objects + ['/OUT:'+dest] ['/EXPORT:init'+ext.name] + objects + ext.extra_objs + ['/OUT:'+dest]
else: else:
cmd += objects + ['-o', dest] + ldflags + ext.ldflags + elib + xlib cmd += objects + ext.extra_objs + ['-o', dest] + ldflags + ext.ldflags + elib + xlib
self.info('\n\n', ' '.join(cmd), '\n\n') self.info('\n\n', ' '.join(cmd), '\n\n')
subprocess.check_call(cmd) subprocess.check_call(cmd)
if iswindows: if iswindows:

View File

@ -195,6 +195,11 @@ os.execv(python, args)
for f in x[-1]: for f in x[-1]:
if f.endswith('.so'): if f.endswith('.so'):
modules.append(os.path.join(x[0], f)) modules.append(os.path.join(x[0], f))
for x in os.walk(os.path.join(frameworks_dir, 'plugins')):
for f in x[-1]:
if f.endswith('.so'):
modules.append(os.path.join(x[0], f))
deps = {} deps = {}
for x in ('Core.1', 'Wand.1'): for x in ('Core.1', 'Wand.1'):
modules.append(os.path.join(root, 'lib', 'libMagick%s.dylib'%x)) modules.append(os.path.join(root, 'lib', 'libMagick%s.dylib'%x))
@ -235,12 +240,21 @@ os.execv(python, args)
shutil.copyfile(pdf, os.path.join(frameworks_dir, os.path.basename(pdf))) shutil.copyfile(pdf, os.path.join(frameworks_dir, os.path.basename(pdf)))
info('\nAdding poppler') info('\nAdding poppler')
for x in ('pdftohtml', 'libpoppler.4.dylib', 'libpoppler-qt4.3.dylib'): popps = []
tgt = os.path.join(frameworks_dir, x) for x in ('bin/pdftohtml', 'lib/libpoppler.5.dylib'):
os.link(os.path.join(os.path.expanduser('~/poppler'), x), tgt) dest = os.path.join(frameworks_dir, os.path.basename(x))
self.fix_qt_dependencies(tgt, self.qt_dependencies(tgt)) popps.append(dest)
shutil.copy2(os.path.join('/Volumes/sw', x), dest)
x ='libpng12.0.dylib'
shutil.copy2('/usr/local/lib/'+x, frameworks_dir)
subprocess.check_call(['install_name_tool', '-id',
'@executable_path/../Frameworks/'+x, os.path.join(frameworks_dir, x)])
self.fix_misc_dependencies(popps)
subprocess.check_call(['install_name_tool', '-change',
'/usr/local/lib/libfontconfig.1.dylib',
'@executable_path/../Frameworks/libfontconfig.1.dylib', popps[1]])
subprocess.check_call(['install_name_tool', '-id',
'@executable_path/../Frameworks/'+os.path.basename(popps[1]), popps[1]])
loader_path = os.path.join(resource_dir, 'loaders') loader_path = os.path.join(resource_dir, 'loaders')
if not os.path.exists(loader_path): if not os.path.exists(loader_path):
@ -286,6 +300,9 @@ os.execv(python, args)
if os.path.exists(dest): if os.path.exists(dest):
shutil.rmtree(dest) shutil.rmtree(dest)
shutil.copytree(os.path.expanduser('~/ImageMagick'), dest, True) shutil.copytree(os.path.expanduser('~/ImageMagick'), dest, True)
shutil.rmtree(os.path.join(dest, 'include'))
shutil.rmtree(os.path.join(dest, 'share', 'doc'))
shutil.rmtree(os.path.join(dest, 'share', 'man'))
shutil.copyfile('/usr/local/lib/libpng12.0.dylib', os.path.join(dest, 'lib', 'libpng12.0.dylib')) shutil.copyfile('/usr/local/lib/libpng12.0.dylib', os.path.join(dest, 'lib', 'libpng12.0.dylib'))
self.fix_image_magick_deps(dest) self.fix_image_magick_deps(dest)

View File

@ -393,7 +393,6 @@ File ::E8A4442D-D0D3-31CD-997A-3CEB641CF5B7 -name IM_MOD_RL_mtv_.dll -parent 8E5
File ::0CA87D0B-5A04-1439-AEE8-C97072D47BA7 -name CORE_RL_tiff_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::0CA87D0B-5A04-1439-AEE8-C97072D47BA7 -name CORE_RL_tiff_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::AC24F520-88D4-D1CF-5797-27C715CE8ACA -name pyexpat.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::AC24F520-88D4-D1CF-5797-27C715CE8ACA -name pyexpat.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::16848F38-71CD-55B8-4D96-1537F6773744 -name IM_MOD_RL_dps_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::16848F38-71CD-55B8-4D96-1537F6773744 -name IM_MOD_RL_dps_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::33A46CC5-BAC4-5863-C83D-303DCCA0CAA1 -name tk85.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::81116DD3-1715-AA87-472F-544FC616EDAF -name IM_MOD_RL_dcm_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::81116DD3-1715-AA87-472F-544FC616EDAF -name IM_MOD_RL_dcm_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::335A4CFB-5C2D-44E4-C438-7018E8244C3D -name ebook-viewer.exe -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::335A4CFB-5C2D-44E4-C438-7018E8244C3D -name ebook-viewer.exe -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::62A16C3B-ED9C-5187-2807-58857DF3A990 -name calibre-debug.exe -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::62A16C3B-ED9C-5187-2807-58857DF3A990 -name calibre-debug.exe -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
@ -507,7 +506,6 @@ File ::9BA85EE5-1754-67AF-736D-481CDCC72DD2 -name _imagingft.pyd -parent 8E5D85A
File ::6254DD0C-8F2C-D4AE-2107-2597D542C181 -name IM_MOD_RL_matte_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::6254DD0C-8F2C-D4AE-2107-2597D542C181 -name IM_MOD_RL_matte_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::F159D566-88D6-C347-3E3C-55C2DDFC5FD0 -name IM_MOD_RL_mono_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::F159D566-88D6-C347-3E3C-55C2DDFC5FD0 -name IM_MOD_RL_mono_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::B873CAA2-011F-94C3-7977-FF344E53C44F -name CORE_RL_jbig_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::B873CAA2-011F-94C3-7977-FF344E53C44F -name CORE_RL_jbig_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::7004FCB8-C6F4-C7AF-08E4-B6151B2F7050 -name tcl85.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::6921F62A-4015-4C9F-98A6-BCBBC43B698E -name msvcm90.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::6921F62A-4015-4C9F-98A6-BCBBC43B698E -name msvcm90.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::7276E0CA-C205-4B18-19A3-157F1B8523FB -name IM_MOD_RL_xtrn_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::7276E0CA-C205-4B18-19A3-157F1B8523FB -name IM_MOD_RL_xtrn_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::7B9624A9-88B4-C61E-6771-9A34FB6CA3B5 -name PyQt4.QtGui.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::7B9624A9-88B4-C61E-6771-9A34FB6CA3B5 -name PyQt4.QtGui.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
@ -570,7 +568,6 @@ File ::8D7A36A6-4517-E995-E989-2E522E7A1438 -name calibre-smtp.exe.local -parent
File ::9E4E5E8F-30C0-E631-9516-2AE01A5CA0E9 -name ebook-device.exe.local -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::9E4E5E8F-30C0-E631-9516-2AE01A5CA0E9 -name ebook-device.exe.local -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::7BE6B538-70D5-A7EB-5F91-E14CE57B394B -name calibre-complete.exe.local -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::7BE6B538-70D5-A7EB-5F91-E14CE57B394B -name calibre-complete.exe.local -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::C4E40030-3EE0-8B05-E6B9-89E81433EE1F -name phonon4.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::C4E40030-3EE0-8B05-E6B9-89E81433EE1F -name phonon4.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::9E84342F-36ED-7ED3-8F90-1EC55267BCFC -name poppler-qt4.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::C9967023-A4C2-856C-1D90-DC710105EBCD -name jpeg62.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::C9967023-A4C2-856C-1D90-DC710105EBCD -name jpeg62.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::B1560042-C99B-9803-552E-21C15F0DFD85 -type dir -name resources -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::B1560042-C99B-9803-552E-21C15F0DFD85 -type dir -name resources -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
File ::DEDE8BE9-D712-2770-A1EC-7E9164CC6D29 -name libpng12.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40 File ::DEDE8BE9-D712-2770-A1EC-7E9164CC6D29 -name libpng12.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40

View File

@ -189,8 +189,7 @@ class BuildEXE(bc):
print '\tAdding unrar' print '\tAdding unrar'
shutil.copyfile(LIBUNRAR, os.path.join(PY2EXE_DIR, os.path.basename(LIBUNRAR))) shutil.copyfile(LIBUNRAR, os.path.join(PY2EXE_DIR, os.path.basename(LIBUNRAR)))
print '\tAdding poppler' print '\tAdding poppler'
for x in (r'utils\Release\pdftohtml.exe', for x in (r'utils\Release\pdftohtml.exe',):
r'qt4\src\Release\poppler-qt4.dll'):
shutil.copyfile(os.path.join(POPPLER, x), shutil.copyfile(os.path.join(POPPLER, x),
os.path.join(PY2EXE_DIR, os.path.basename(x))) os.path.join(PY2EXE_DIR, os.path.basename(x)))
for x in ('jpeg62', 'zlib1', 'libpng12'): for x in ('jpeg62', 'zlib1', 'libpng12'):
@ -281,7 +280,8 @@ def main(args=sys.argv):
'excludes' : ["Tkconstants", "Tkinter", "tcl", 'excludes' : ["Tkconstants", "Tkinter", "tcl",
"_imagingtk", "ImageTk", "FixTk" "_imagingtk", "ImageTk", "FixTk"
], ],
'dll_excludes' : ['mswsock.dll'], 'dll_excludes' : ['mswsock.dll', 'tcl85.dll',
'tk85.dll'],
}, },
}, },

View File

@ -340,17 +340,17 @@ void PNGMemWriter::init(vector<char> *buf, int width, int height) {
} }
/*
void calibre_jpeg_error_exit (j_common_ptr cinfo) void calibre_jpeg_error_exit (j_common_ptr cinfo)
{ {
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ // cinfo->err really points to a my_error_mgr struct, so coerce pointer
calibre_jpeg_err_mgr *err = (calibre_jpeg_err_mgr *)(cinfo->err); calibre_jpeg_err_mgr *err = (calibre_jpeg_err_mgr *)(cinfo->err);
/* Always display the message. */ // Always display the message.
/* We could postpone this until after returning, if we chose. */ // We could postpone this until after returning, if we chose.
//(*cinfo->err->output_message) (cinfo); //(*cinfo->err->output_message) (cinfo);
/* Return control to the setjmp point */ // Return control to the setjmp point
longjmp(err->setjmp_buffer, 1); longjmp(err->setjmp_buffer, 1);
} }
@ -366,7 +366,7 @@ JPEGWriter::JPEGWriter() {
void JPEGWriter::init(int width, int height) { void JPEGWriter::init(int width, int height) {
cinfo.image_width = width; cinfo.image_width = width;
cinfo.image_height = height; cinfo.image_height = height;
cinfo.input_components = 3; /* # of color components per pixel */ cinfo.input_components = 3; // # of color components per pixel
cinfo.in_color_space = JCS_RGB; cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&this->cinfo); jpeg_set_defaults(&this->cinfo);
this->check(); this->check();
@ -387,7 +387,7 @@ void JPEGWriter::check() {
void JPEGWriter::raise() { void JPEGWriter::raise() {
char buffer[JMSG_LENGTH_MAX]; char buffer[JMSG_LENGTH_MAX];
/* Create the message */ // Create the message
(*this->cinfo.err->format_message) ((jpeg_common_struct *)(&this->cinfo), buffer); (*this->cinfo.err->format_message) ((jpeg_common_struct *)(&this->cinfo), buffer);
jpeg_destroy_compress(&this->cinfo); jpeg_destroy_compress(&this->cinfo);
throw ReflowException(buffer); throw ReflowException(buffer);
@ -422,3 +422,4 @@ void JPEGWriter::write_splash_bitmap(SplashBitmap *bitmap) {
JPEGWriter::~JPEGWriter() { JPEGWriter::~JPEGWriter() {
jpeg_destroy_compress(&this->cinfo); jpeg_destroy_compress(&this->cinfo);
} }
*/

View File

@ -99,11 +99,11 @@ namespace calibre_reflow {
vector<string*> str() const; vector<string*> str() const;
void clear(); void clear();
}; };
/*
struct calibre_jpeg_err_mgr { struct calibre_jpeg_err_mgr {
struct jpeg_error_mgr pub; /* "public" fields */ struct jpeg_error_mgr pub; // "public" fields
jmp_buf setjmp_buffer; /* for return to caller */ jmp_buf setjmp_buffer; // for return to caller
}; };
class JPEGWriter { class JPEGWriter {
@ -125,6 +125,6 @@ namespace calibre_reflow {
void write_image(JSAMPARRAY image_buffer, JDIMENSION number_of_scanlines); void write_image(JSAMPARRAY image_buffer, JDIMENSION number_of_scanlines);
void write_splash_bitmap(SplashBitmap *bitmap); void write_splash_bitmap(SplashBitmap *bitmap);
}; };
*/
} }
#endif #endif

View File

@ -47,29 +47,32 @@ extern "C" {
if (!PyArg_ParseTuple(args, "s#O", &pdfdata, &size, &cover)) if (!PyArg_ParseTuple(args, "s#O", &pdfdata, &size, &cover))
return NULL; return NULL;
Reflow *reflow = NULL;
try { try {
Reflow reflow(pdfdata, static_cast<std::ifstream::pos_type>(size)); reflow = new Reflow(pdfdata, size);
info = reflow.get_info(); info = reflow->get_info();
if (PyObject_IsTrue(cover)) { if (PyObject_IsTrue(cover)) {
if (!reflow.is_locked()) { if (!reflow->is_locked() && reflow->numpages() > 0) {
vector<char> *data = reflow.render_first_page(); vector<char> *data = reflow->render_first_page();
if (data->size() > 0) { if (data && data->size() > 0) {
PyObject *d = PyBytes_FromStringAndSize(&((*data)[0]), data->size()); PyObject *d = PyBytes_FromStringAndSize(&((*data)[0]), data->size());
delete data; delete data;
if (d == NULL) return PyErr_NoMemory(); if (d == NULL) {delete reflow; return PyErr_NoMemory();}
if (PyDict_SetItemString(ans, "cover", d) == -1) return NULL; if (PyDict_SetItemString(ans, "cover", d) == -1) {delete reflow; return NULL;}
Py_XDECREF(d); Py_XDECREF(d);
} }
} else { } else {
if (PyDict_SetItemString(ans, "cover", Py_None) == -1) return NULL; if (PyDict_SetItemString(ans, "cover", Py_None) == -1) {delete reflow; return NULL;}
} }
} }
} catch (std::exception &e) { } catch (std::exception &e) {
PyErr_SetString(PyExc_RuntimeError, e.what()); return NULL; PyErr_SetString(PyExc_RuntimeError, e.what()); delete reflow; return NULL;
} catch (...) { } catch (...) {
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError,
"Unknown exception raised while getting metadata from PDF"); return NULL; "Unknown exception raised while getting metadata from PDF"); delete reflow; return NULL;
} }
delete reflow; reflow = NULL;
for (map<string,string>::const_iterator it = info.begin() ; it != info.end(); it++ ) { for (map<string,string>::const_iterator it = info.begin() ; it != info.end(); it++ ) {
PyObject *key = PyUnicode_Decode((*it).first.c_str(), (*it).first.size(), "UTF-8", "replace"); PyObject *key = PyUnicode_Decode((*it).first.c_str(), (*it).first.size(), "UTF-8", "replace");

View File

@ -3,11 +3,6 @@
* License: GNU GPL v3 * License: GNU GPL v3
*/ */
#ifdef _WIN32
#include <poppler/Object.h>
#else
#include <Object.h>
#endif
#include <Outline.h> #include <Outline.h>
#include <PDFDocEncoding.h> #include <PDFDocEncoding.h>
#include <goo/GooList.h> #include <goo/GooList.h>
@ -25,6 +20,8 @@ static const char* info_keys[num_info_keys] = {
"Title", "Subject", "Keywords", "Author", "Creator", "Producer", "Title", "Subject", "Keywords", "Author", "Creator", "Producer",
"CreationDate", "ModDate" "CreationDate", "ModDate"
}; };
static char encoding[10] = "UTF-8";
static char yes[10] = "yes";
//------------------------------------------------------------------------ //------------------------------------------------------------------------
@ -684,30 +681,16 @@ void XMLOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
colorMap, interpolate, maskColors, inlineImg); colorMap, interpolate, maskColors, inlineImg);
} }
static char stream_pdf[15] = "stream.pdf";
class MemInStream : public MemStream {
private:
GooString stream_name;
public:
MemInStream(char *buf, size_t st, size_t sz, Object *obj) :
MemStream(buf, st, sz, obj), stream_name(stream_pdf) {}
~MemInStream() {}
GooString *getFileName() { return &this->stream_name; }
};
Reflow::Reflow(char *pdfdata, size_t sz) : Reflow::Reflow(char *pdfdata, size_t sz) :
pdfdata(pdfdata), current_font_size(-1), doc(NULL) pdfdata(pdfdata), current_font_size(-1), doc(NULL), obj()
{ {
Object obj; this->obj.initNull();
obj.initNull();
if (globalParams == NULL) { if (globalParams == NULL) {
globalParams = new GlobalParams(); globalParams = new GlobalParams();
if (!globalParams) if (!globalParams)
throw ReflowException("Failed to allocate Globalparams"); throw ReflowException("Failed to allocate Globalparams");
} }
MemInStream *str = new MemInStream(pdfdata, 0, sz, &obj); MemStream *str = new MemStream(pdfdata, 0, sz, &this->obj);
this->doc = new PDFDoc(str, NULL, NULL); this->doc = new PDFDoc(str, NULL, NULL);
if (!this->doc->isOk()) { if (!this->doc->isOk()) {
@ -730,7 +713,6 @@ Reflow::render() {
if (!this->doc->okToCopy()) if (!this->doc->okToCopy())
cout << "Warning, this document has the copy protection flag set, ignoring." << endl; cout << "Warning, this document has the copy protection flag set, ignoring." << endl;
char encoding[10] = "UTF-8";
globalParams->setTextEncoding(encoding); globalParams->setTextEncoding(encoding);
int first_page = 1; int first_page = 1;
@ -808,7 +790,6 @@ map<string, string> Reflow::get_info() {
Object info; Object info;
map<string, string> ans; map<string, string> ans;
string val; string val;
char encoding[10] = "UTF-8";
globalParams->setTextEncoding(encoding); globalParams->setTextEncoding(encoding);
this->doc->getDocInfo(&info); this->doc->getDocInfo(&info);
@ -832,7 +813,7 @@ string Reflow::decode_info_string(Dict *info, const char *key) const {
int i, n; int i, n;
ostringstream oss; ostringstream oss;
char *tmp = new char[strlen(key)+1]; char *tmp = new char[strlen(key)+1];
strcpy(tmp, key); strncpy(tmp, key, strlen(key)+1);
UnicodeMap *umap; UnicodeMap *umap;
if (!(umap = globalParams->getTextEncoding())) { if (!(umap = globalParams->getTextEncoding())) {
throw ReflowException("Failed to allocate unicode map."); throw ReflowException("Failed to allocate unicode map.");
@ -871,8 +852,7 @@ string Reflow::decode_info_string(Dict *info, const char *key) const {
vector<char>* Reflow::render_first_page(bool use_crop_box, double x_res, vector<char>* Reflow::render_first_page(bool use_crop_box, double x_res,
double y_res) { double y_res) {
if (this->is_locked()) throw ReflowException("Document is locked."); if (this->is_locked()) throw ReflowException("Document is locked.");
char encoding[10] = "UTF-8"; if (this->numpages() < 1) throw ReflowException("Document has no pages.");
char yes[10] = "yes";
globalParams->setTextEncoding(encoding); globalParams->setTextEncoding(encoding);
globalParams->setEnableFreeType(yes); globalParams->setEnableFreeType(yes);
globalParams->setAntialias(yes); globalParams->setAntialias(yes);
@ -882,11 +862,14 @@ vector<char>* Reflow::render_first_page(bool use_crop_box, double x_res,
paper_color[0] = 255; paper_color[0] = 255;
paper_color[1] = 255; paper_color[1] = 255;
paper_color[2] = 255; paper_color[2] = 255;
SplashOutputDev *out = new SplashOutputDev(splashModeRGB8, 4, false, paper_color); SplashOutputDev *out = new SplashOutputDev(splashModeRGB8, 4, false, paper_color, true, true);
out->setVectorAntialias(true);
if (!out) { if (!out) {
throw ReflowException("Failed to allocate SplashOutputDev"); throw ReflowException("Failed to allocate SplashOutputDev");
} }
try {
out->startDoc(doc->getXRef()); out->startDoc(doc->getXRef());
out->startPage(1, NULL);
double pg_w, pg_h; double pg_w, pg_h;
int pg = 1; int pg = 1;
@ -905,14 +888,19 @@ vector<char>* Reflow::render_first_page(bool use_crop_box, double x_res,
int x=0, y=0; int x=0, y=0;
this->doc->displayPageSlice(out, pg, x_res, y_res, 0, this->doc->displayPageSlice(out, pg, x_res, y_res, 0,
!use_crop_box, false, false, x, y, pg_w, pg_h); !use_crop_box, false, false, x, y, pg_w, pg_h);
} catch(...) { delete out; throw; }
SplashBitmap *bmp = out->getBitmap(); SplashBitmap *bmp = out->takeBitmap();
out->endPage();
delete out; out = NULL;
PNGMemWriter writer; PNGMemWriter writer;
vector<char> *buf = new vector<char>(); vector<char> *buf = new vector<char>();
try {
writer.init(buf, bmp->getWidth(), bmp->getHeight()); writer.init(buf, bmp->getWidth(), bmp->getHeight());
writer.write_splash_bitmap(bmp); writer.write_splash_bitmap(bmp);
writer.close(); writer.close();
delete out; } catch(...) { delete buf; delete bmp; throw; }
delete bmp;
return buf; return buf;
} }
@ -967,4 +955,3 @@ string Reflow::set_info(map<char *, char *> sinfo) {
return ans; return ans;
} }

View File

@ -8,6 +8,14 @@
#define CALIBRE_REFLOW #define CALIBRE_REFLOW
#define UNICODE #define UNICODE
#ifdef _WIN32
#include <poppler/Object.h>
#elif defined(_OSX)
#include <poppler/Object.h>
#else
#include <Object.h>
#endif
#include <PDFDoc.h> #include <PDFDoc.h>
#include <GlobalParams.h> #include <GlobalParams.h>
#include <GfxState.h> #include <GfxState.h>
@ -23,7 +31,6 @@
#include <iostream> #include <iostream>
#include <algorithm> #include <algorithm>
#include <fstream> #include <fstream>
#include <iostream>
#include <iomanip> #include <iomanip>
#include <map> #include <map>
#include <errno.h> #include <errno.h>
@ -49,6 +56,7 @@ class Reflow {
char *pdfdata; char *pdfdata;
double current_font_size; double current_font_size;
PDFDoc *doc; PDFDoc *doc;
Object obj;
string decode_info_string(Dict *info, const char *key) const; string decode_info_string(Dict *info, const char *key) const;
void outline_level(ostringstream *oss, GooList *items, void outline_level(ostringstream *oss, GooList *items,
@ -76,6 +84,9 @@ class Reflow {
/* Set the info dictionary. Currently broken. */ /* Set the info dictionary. Currently broken. */
string set_info(map<char *, char *> info); string set_info(map<char *, char *> info);
/* Number of pages in the document */
int numpages() { return this->doc->getNumPages(); }
}; };
class XMLString { class XMLString {

View File

@ -5,8 +5,8 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: calibre 0.6.13\n" "Project-Id-Version: calibre 0.6.13\n"
"POT-Creation-Date: 2009-09-18 12:45+MDT\n" "POT-Creation-Date: 2009-09-25 11:00+MDT\n"
"PO-Revision-Date: 2009-09-18 12:45+MDT\n" "PO-Revision-Date: 2009-09-25 11:00+MDT\n"
"Last-Translator: Automatically generated\n" "Last-Translator: Automatically generated\n"
"Language-Team: LANGUAGE\n" "Language-Team: LANGUAGE\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -51,8 +51,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:444 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:444
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:870 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:870
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdb.py:39 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdb.py:39
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:34 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:21
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:76
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/topaz.py:29 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/topaz.py:29
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/txt.py:14 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/txt.py:14
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:44 #: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:44
@ -132,8 +131,6 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:45 #: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:45
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:63 #: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:77 #: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:77
#: /home/kovid/work/calibre/src/calibre/utils/poppler/__init__.py:28
#: /home/kovid/work/calibre/src/calibre/utils/poppler/__init__.py:32
msgid "Unknown" msgid "Unknown"
msgstr "" msgstr ""
@ -313,11 +310,11 @@ msgstr ""
msgid "No valid plugin found in " msgid "No valid plugin found in "
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/ui.py:229 #: /home/kovid/work/calibre/src/calibre/customize/ui.py:232
msgid "Initialization of plugin %s failed with traceback:" msgid "Initialization of plugin %s failed with traceback:"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/ui.py:359 #: /home/kovid/work/calibre/src/calibre/customize/ui.py:362
msgid "" msgid ""
" %prog options\n" " %prog options\n"
"\n" "\n"
@ -325,27 +322,27 @@ msgid ""
" " " "
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/ui.py:365 #: /home/kovid/work/calibre/src/calibre/customize/ui.py:368
msgid "Add a plugin by specifying the path to the zip file containing it." msgid "Add a plugin by specifying the path to the zip file containing it."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/ui.py:367 #: /home/kovid/work/calibre/src/calibre/customize/ui.py:370
msgid "Remove a custom plugin by name. Has no effect on builtin plugins" msgid "Remove a custom plugin by name. Has no effect on builtin plugins"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/ui.py:369 #: /home/kovid/work/calibre/src/calibre/customize/ui.py:372
msgid "Customize plugin. Specify name of plugin and customization string separated by a comma." msgid "Customize plugin. Specify name of plugin and customization string separated by a comma."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/ui.py:371 #: /home/kovid/work/calibre/src/calibre/customize/ui.py:374
msgid "List all installed plugins" msgid "List all installed plugins"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/ui.py:373 #: /home/kovid/work/calibre/src/calibre/customize/ui.py:376
msgid "Enable the named plugin" msgid "Enable the named plugin"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/ui.py:375 #: /home/kovid/work/calibre/src/calibre/customize/ui.py:378
msgid "Disable the named plugin" msgid "Disable the named plugin"
msgstr "" msgstr ""
@ -2038,7 +2035,7 @@ msgid "input"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/comic_input_ui.py:84 #: /home/kovid/work/calibre/src/calibre/gui2/convert/comic_input_ui.py:84
#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:45 #: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:49
#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:41 #: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output_ui.py:41
#: /home/kovid/work/calibre/src/calibre/gui2/convert/fb2_input_ui.py:28 #: /home/kovid/work/calibre/src/calibre/gui2/convert/fb2_input_ui.py:28
#: /home/kovid/work/calibre/src/calibre/gui2/convert/fb2_output_ui.py:28 #: /home/kovid/work/calibre/src/calibre/gui2/convert/fb2_output_ui.py:28
@ -2133,7 +2130,7 @@ msgid "Debug the conversion process."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug.py:38 #: /home/kovid/work/calibre/src/calibre/gui2/convert/debug.py:38
#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:47 #: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:51
msgid "Choose debug folder" msgid "Choose debug folder"
msgstr "" msgstr ""
@ -2145,12 +2142,12 @@ msgstr ""
msgid "Failed to create debug directory" msgid "Failed to create debug directory"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:46 #: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:50
msgid "Choose a folder to put the debug output into. If you specify a folder, calibre will place a lot of debug output into it. This will be useful in understanding the conversion process and figuring out the correct values for conversion parameters like Table of Contents and Chapter Detection." msgid "Choose a folder to put the debug output into. If you specify a folder, calibre will place a lot of debug output into it. This will be useful in understanding the conversion process and figuring out the correct values for conversion parameters like Table of Contents and Chapter Detection."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:48 #: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:52
#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:49 #: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:53
#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:170 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:170
#: /home/kovid/work/calibre/src/calibre/gui2/convert/xexp_edit_ui.py:44 #: /home/kovid/work/calibre/src/calibre/gui2/convert/xexp_edit_ui.py:44
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:61 #: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget_ui.py:61
@ -2182,6 +2179,10 @@ msgstr ""
msgid "..." msgid "..."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/debug_ui.py:54
msgid "The debug process outputs the intermediate HTML generated at various stages of the conversion process. This HTML can sometimes serve as a good starting point for hand editing a conversion."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output.py:15 #: /home/kovid/work/calibre/src/calibre/gui2/convert/epub_output.py:15
msgid "EPUB Output" msgid "EPUB Output"
msgstr "" msgstr ""
@ -6342,6 +6343,7 @@ msgid "Traditional Chinese"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:99 #: /home/kovid/work/calibre/src/calibre/utils/localization.py:99
#: /home/kovid/work/calibre/src/calibre/web/feeds/recipes/recipe_nytimes.py:17
msgid "English" msgid "English"
msgstr "" msgstr ""