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

Revision 463, 5.5 kB (checked in by jerome, 17 years ago)

Licensing terms changed to GNU GPL v3.0 or higher.
Removed old PCL3/4/5 parser which for a long time now wasn't used
anymore, and for which I was not the original copyright owner.
Version number bumped to 3.00alpha to reflect licensing changes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Auth Date Id Rev
RevLine 
[192]1#
2# pkpgcounter : a generic Page Description Language parser
3#
[443]4# (c) 2003, 2004, 2005, 2006, 2007 Jerome Alet <alet@librelogiciel.com>
[463]5# This program is free software: you can redistribute it and/or modify
[192]6# it under the terms of the GNU General Public License as published by
[463]7# the Free Software Foundation, either version 3 of the License, or
[192]8# (at your option) any later version.
[463]9#
[192]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
[463]16# along with this program.  If not, see <http://www.gnu.org/licenses/>.
[192]17#
18# $Id$
19#
20
[360]21"""This module defines the base class for all Page Description Language parsers."""
22
[199]23import sys
[428]24import os
[371]25import popen2
[199]26
[220]27KILOBYTE = 1024   
28MEGABYTE = 1024 * KILOBYTE   
29FIRSTBLOCKSIZE = 16 * KILOBYTE
30LASTBLOCKSIZE = int(KILOBYTE / 4)
31
[193]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       
[192]41class PDLParser :
42    """Generic PDL parser."""
[428]43    totiffcommands = None        # Default command to convert to TIFF
[220]44    def __init__(self, infile, debug=0, firstblock=None, lastblock=None) :
[192]45        """Initialize the generic parser."""
[220]46        self.infile = infile
[192]47        self.debug = debug
[220]48        if firstblock is None :
49            self.infile.seek(0)
50            firstblock = self.infile.read(FIRSTBLOCKSIZE)
51            try :
52                self.infile.seek(-LASTBLOCKSIZE, 2)
53                lastblock = self.infile.read(LASTBLOCKSIZE)
54            except IOError :   
55                lastblock = ""
56            self.infile.seek(0)
57        self.firstblock = firstblock
58        self.lastblock = lastblock
59        if not self.isValid() :
60            raise PDLParserError, "Invalid file format !"
61        try :
62            import psyco 
63        except ImportError :   
64            pass # Psyco is not installed
65        else :   
66            # Psyco is installed, tell it to compile
67            # the CPU intensive methods : PCL and PCLXL
[432]68            # parsing will greatly benefit from this.
[220]69            psyco.bind(self.getJobSize)
70           
[252]71    def logdebug(self, message) :       
72        """Logs a debug message if needed."""
73        if self.debug :
74            sys.stderr.write("%s\n" % message)
75           
[220]76    def isValid(self) :   
[387]77        """Returns True if data is in the expected format, else False."""
[192]78        raise RuntimeError, "Not implemented !"
[220]79       
80    def getJobSize(self) :   
81        """Counts pages in a document."""
82        raise RuntimeError, "Not implemented !"
[362]83       
[363]84    def convertToTiffMultiPage24NC(self, fname, dpi) :
[362]85        """Converts the input file to TIFF format, X dpi, 24 bits per pixel, uncompressed.
[363]86           Writes TIFF datas to the file named by fname.
[362]87        """   
[428]88        if self.totiffcommands :
89            for totiffcommand in self.totiffcommands :
90                self.infile.seek(0)
91                error = False
92                commandline = totiffcommand % locals()
93                child = popen2.Popen4(commandline)
[371]94                try :
[428]95                    try :
96                        data = self.infile.read(MEGABYTE)   
97                        while data :
98                            child.tochild.write(data)
[429]99                            child.tochild.flush()
[428]100                            data = self.infile.read(MEGABYTE)
101                    except (IOError, OSError) :   
102                        error = True
103                finally :   
104                    child.tochild.close()   
[429]105                    dummy = child.fromchild.read()
[428]106                    child.fromchild.close()
107                   
108                try :
[432]109                    status = child.wait()
[428]110                except OSError :   
111                    error = True
[432]112                else :   
113                    if os.WIFEXITED(status) :
114                        if os.WEXITSTATUS(status) :
115                            error = True
116                    else :       
117                        error = True
[428]118                   
119                if not os.path.exists(fname) :
120                    error = True
121                elif not os.stat(fname).st_size :
122                    error = True
123                else :       
124                    break       # Conversion worked fine it seems.
125                self.logdebug("Command failed : %s" % repr(commandline))
126            if error :
127                raise PDLParserError, "Problem during conversion to TIFF."
[371]128        else :       
129            raise PDLParserError, "Impossible to compute ink coverage for this file format."
[415]130           
131def test(parserclass) :       
132    """Test function."""
133    if (len(sys.argv) < 2) or ((not sys.stdin.isatty()) and ("-" not in sys.argv[1:])) :
134        sys.argv.append("-")
135    totalsize = 0   
136    for arg in sys.argv[1:] :
137        if arg == "-" :
138            infile = sys.stdin
139            mustclose = 0
140        else :   
[450]141            infile = open(arg, "rbU")
[415]142            mustclose = 1
143        try :
144            parser = parserclass(infile, debug=1)
145            totalsize += parser.getJobSize()
146        except PDLParserError, msg :   
147            sys.stderr.write("ERROR: %s\n" % msg)
148            sys.stderr.flush()
149        if mustclose :   
150            infile.close()
151    print "%s" % totalsize
152   
Note: See TracBrowser for help on using the browser.