Changeset 1462

Show
Ignore:
Timestamp:
05/08/04 17:12:23 (20 years ago)
Author:
jalet
Message:

Improved PCL6 support

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/bin/pkpgcounter

    r1461 r1462  
    2424# 
    2525# $Log$ 
     26# Revision 1.8  2004/05/08 15:12:23  jalet 
     27# Improved PCL6 support 
     28# 
    2629# Revision 1.7  2004/05/07 23:08:21  jalet 
    2730# Skeleton for PCLXL aka PCL6 
     
    5255import os 
    5356import mmap 
     57import struct 
    5458import tempfile 
    5559 
     60def debug(msg) : 
     61    """Outputs a debug message on stderr.""" 
     62    sys.stderr.write("%s\n" % msg) 
     63    sys.stderr.flush() 
     64     
    5665def ispostscript(data) :     
    5766    """Returns 1 if data is PostScript, else 0.""" 
     
    208217        return copies * pagecount 
    209218 
     219class PCLXLParser : 
     220    def __init__(self, infile) : 
     221        """Initialize PCLXL parser.""" 
     222        self.infile = infile 
     223        self.islittleendian = None 
     224        found = 0 
     225        while not found : 
     226            line = self.infile.readline() 
     227            if not line : 
     228                break 
     229            if line[1:12] == " HP-PCL XL;" : 
     230                found = 1 
     231                if line[0] == ")" : 
     232                    self.littleendian() 
     233                elif line[0] == "(" :     
     234                    self.bigendian() 
     235        if not found : 
     236            raise TypeError, "This file doesn't seem to be PCLXL (aka PCL6)" 
     237        else :     
     238            self.tags = [None] * 256     
     239            self.tags[0x28] = self.bigendian    # big endian 
     240            self.tags[0x29] = self.littleendian # big endian 
     241            self.tags[0x43] = self.beginPage    # BeginPage 
     242            self.tags[0x44] = self.endPage      # EndPage 
     243             
     244            self.tags[0xc0] = 1 # ubyte 
     245            self.tags[0xc1] = 2 # uint16 
     246            self.tags[0xc2] = 4 # uint32 
     247            self.tags[0xc3] = 2 # sint16 
     248            self.tags[0xc4] = 4 # sint32 
     249            self.tags[0xc5] = 4 # real32 
     250             
     251            self.tags[0xc8] = self.array_8  # ubyte_array 
     252            self.tags[0xc9] = self.array_16 # uint16_array 
     253            self.tags[0xca] = self.array_32 # uint32_array 
     254            self.tags[0xcb] = self.array_16 # sint16_array 
     255            self.tags[0xcc] = self.array_32 # sint32_array 
     256            self.tags[0xcd] = self.array_32 # real32_array 
     257             
     258            self.tags[0xd0] = 2 # ubyte_xy 
     259            self.tags[0xd1] = 4 # uint16_xy 
     260            self.tags[0xd2] = 8 # uint32_xy 
     261            self.tags[0xd3] = 4 # sint16_xy 
     262            self.tags[0xd4] = 8 # sint32_xy 
     263            self.tags[0xd5] = 8 # real32_xy 
     264             
     265            self.tags[0xd0] = 4  # ubyte_box 
     266            self.tags[0xd1] = 8  # uint16_box 
     267            self.tags[0xd2] = 16 # uint32_box 
     268            self.tags[0xd3] = 8  # sint16_box 
     269            self.tags[0xd4] = 16 # sint32_box 
     270            self.tags[0xd5] = 16 # real32_box 
     271             
     272            self.tags[0xf8] = 1 # attr_ubyte 
     273            self.tags[0xf9] = 2 # attr_uint16 
     274             
     275            self.tags[0xfa] = self.embeddedData      # dataLength 
     276            self.tags[0xfb] = self.embeddedDataSmall # dataLengthByte 
     277             
     278    def beginPage(self) : 
     279        """Indicates the beginning of a new page.""" 
     280        self.pagecount += 1 
     281        debug("Begin page %i at %s" % (self.pagecount, self.infile.tell())) 
     282         
     283    def endPage(self) : 
     284        """Indicates the end of a page.""" 
     285        debug("End page %i at %s" % (self.pagecount, self.infile.tell())) 
     286         
     287    def handleArray(self, itemsize) :         
     288        """Handles arrays.""" 
     289        datatype = self.infile.read(1) 
     290        length = self.tags[ord(datatype)] 
     291        sarraysize = self.infile.read(length) 
     292        if self.islittleendian : 
     293            fmt = "<" 
     294        else :     
     295            fmt = ">" 
     296        if length == 1 :     
     297            fmt += "B" 
     298        elif length == 2 :     
     299            fmt += "H" 
     300        elif length == 4 :     
     301            fmt += "I" 
     302        else :     
     303            raise TypeError, "Error on array size at %s" % self.infile.tell() 
     304        arraysize = struct.unpack(fmt, sarraysize)[0] 
     305        return arraysize * itemsize 
     306         
     307    def array_8(self) :     
     308        """Handles byte arrays.""" 
     309        return self.handleArray(1) 
     310         
     311    def array_16(self) :     
     312        """Handles byte arrays.""" 
     313        return self.handleArray(2) 
     314         
     315    def array_32(self) :     
     316        """Handles byte arrays.""" 
     317        return self.handleArray(4) 
     318         
     319    def embeddedDataSmall(self) : 
     320        """Handle small amounts of data.""" 
     321        return ord(self.infile.read(1)) 
     322         
     323    def embeddedData(self) : 
     324        """Handle normal amounts of data.""" 
     325        if self.islittleendian : 
     326            fmt = "<I" 
     327        else :     
     328            fmt = ">I" 
     329        return struct.unpack(fmt, self.infile.read(4))[0] 
     330         
     331    def littleendian(self) :         
     332        """Toggles to little endianness.""" 
     333        self.islittleendian = 1 # little endian 
     334         
     335    def bigendian(self) :     
     336        """Toggles to big endianness.""" 
     337        self.islittleendian = 0 # big endian 
     338     
     339    def pagecount(self) : 
     340        """Counts pages in a PCLXL (PCL6) document.""" 
     341        self.pagecount = 0 
     342        while 1 : 
     343            pos = self.infile.tell() 
     344            char = self.infile.read(1) 
     345            if not char : 
     346                break 
     347            index = ord(char)     
     348            length = self.tags[index] 
     349            if length is not None : 
     350                if not length : 
     351                    debug("Unrecognized tag 0x%02x at %s\n" % (index, self.infile.tell())) 
     352                elif callable(length) :     
     353                    length = length() 
     354                if length :     
     355                    self.infile.read(length)     
     356        return self.pagecount 
     357         
    210358def pclxl(infile) :      
    211359    """Count pages in a PCL6 aka PCLXL document.""" 
    212     raise TypeError, "Sorry but PCL6, aka PCLXL, is not supported yet.\n" 
     360    parser = PCLXLParser(infile)     
     361    return parser.pagecount() 
    213362     
    214363def smartpagecounter(filename) : 
     
    236385        size = postscript(infile) 
    237386    elif ispclxl(firstblock) :     
     387        raise TypeError, "PCLXL (aka PCL6) is not supported yet." 
    238388        size = pclxl(infile) 
    239389    elif ispcl(firstblock) :     
     
    251401    totalsize = 0     
    252402    for arg in sys.argv[1:] : 
    253         totalsize += smartpagecounter(arg) 
     403        try : 
     404            totalsize += smartpagecounter(arg) 
     405        except TypeError, msg :     
     406            debug(msg) 
    254407    print "%s" % totalsize