root / pkpgcounter / trunk / pkpgpdls / pdlparser.py @ 491

Revision 491, 5.5 kB (checked in by jerome, 16 years ago)

Major code cleaning. Now clearer, although probably a bit slower since
a file can be opened several times.
Now universal line opening mode is only used when needed (PS, PDF and plain
text), and binary opening mode is used for the other formats.
This mean we will be able to remove mmap calls wherever possible, finally.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Auth Date Id Rev
Line 
1#
2# pkpgcounter : a generic Page Description Language parser
3#
4# (c) 2003, 2004, 2005, 2006, 2007 Jerome Alet <alet@librelogiciel.com>
5# This program is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program.  If not, see <http://www.gnu.org/licenses/>.
17#
18# $Id$
19#
20
21"""This module defines the base class for all Page Description Language parsers."""
22
23import sys
24import os
25import popen2
26
27KILOBYTE = 1024   
28MEGABYTE = 1024 * KILOBYTE   
29FIRSTBLOCKSIZE = 16 * KILOBYTE
30LASTBLOCKSIZE = int(KILOBYTE / 4)
31
32class PDLParserError(Exception):
33    """An exception for PDLParser related stuff."""
34    def __init__(self, message = ""):
35        self.message = message
36        Exception.__init__(self, message)
37    def __repr__(self):
38        return self.message
39    __str__ = __repr__
40       
41class PDLParser :
42    """Generic PDL parser."""
43    totiffcommands = None        # Default command to convert to TIFF
44    openmode = "rb"              # Default file opening mode
45    def __init__(self, filename, debug=0) :
46        """Initialize the generic parser."""
47        self.filename = filename
48        self.debug = debug
49        self.infile = None
50        (self.firstblock, self.lastblock) = self.readBlocks()
51        self.infile = open(self.filename, self.openmode)
52        if not self.isValid() :
53            raise PDLParserError, "Invalid file format !"
54        try :
55            import psyco 
56        except ImportError :   
57            pass # Psyco is not installed
58        else :   
59            # Psyco is installed, tell it to compile
60            # the CPU intensive methods : PCL and PCLXL
61            # parsing will greatly benefit from this.
62            psyco.bind(self.getJobSize)
63           
64    def __del__(self) :
65        """Ensures the input file gets closed."""
66        if self.infile :
67            self.infile.close()
68           
69    def readBlocks(self) :       
70        """Reads first and last block of the input file."""
71        infile = open(self.filename, "rb")
72        try :
73            firstblock = infile.read(FIRSTBLOCKSIZE)
74            try :
75                infile.seek(-LASTBLOCKSIZE, 2)
76                lastblock = infile.read(LASTBLOCKSIZE)
77            except IOError :   
78                lastblock = ""
79        finally :       
80            infile.close()
81        return (firstblock, lastblock)   
82           
83    def logdebug(self, message) :       
84        """Logs a debug message if needed."""
85        if self.debug :
86            sys.stderr.write("%s\n" % message)
87           
88    def isValid(self) :   
89        """Returns True if data is in the expected format, else False."""
90        raise RuntimeError, "Not implemented !"
91       
92    def getJobSize(self) :   
93        """Counts pages in a document."""
94        raise RuntimeError, "Not implemented !"
95       
96    def convertToTiffMultiPage24NC(self, fname, dpi) :
97        """Converts the input file to TIFF format, X dpi, 24 bits per pixel, uncompressed.
98           Writes TIFF datas to the file named by fname.
99        """   
100        if self.totiffcommands :
101            infile = open(self.filename, "rb")
102            try :
103                for totiffcommand in self.totiffcommands :
104                    infile.seek(0)
105                    error = False
106                    commandline = totiffcommand % locals()
107                    child = popen2.Popen4(commandline)
108                    try :
109                        try :
110                            data = infile.read(MEGABYTE)   
111                            while data :
112                                child.tochild.write(data)
113                                child.tochild.flush()
114                                data = infile.read(MEGABYTE)
115                        except (IOError, OSError) :   
116                            error = True
117                    finally :   
118                        child.tochild.close()   
119                        dummy = child.fromchild.read()
120                        child.fromchild.close()
121                       
122                    try :
123                        status = child.wait()
124                    except OSError :   
125                        error = True
126                    else :   
127                        if os.WIFEXITED(status) :
128                            if os.WEXITSTATUS(status) :
129                                error = True
130                        else :       
131                            error = True
132                       
133                    if not os.path.exists(fname) :
134                        error = True
135                    elif not os.stat(fname).st_size :
136                        error = True
137                    else :       
138                        break       # Conversion worked fine it seems.
139                    self.logdebug("Command failed : %s" % repr(commandline))
140            finally :       
141                infile.close()
142            if error :
143                raise PDLParserError, "Problem during conversion to TIFF."
144        else :       
145            raise PDLParserError, "Impossible to compute ink coverage for this file format."
Note: See TracBrowser for help on using the browser.