Show
Ignore:
Timestamp:
02/09/06 22:52:21 (19 years ago)
Author:
jerome
Message:

Simplified the PCLXL parser. This gives a 10% speedup.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • pkpgcounter/trunk/pkpgpdls/pclxl.py

    r314 r316  
    8888            return 0 
    8989             
    90     def beginPage(self) : 
     90    def beginPage(self, prevpos) : 
    9191        """Indicates the beginning of a new page, and extracts media information.""" 
    9292        self.pagecount += 1 
     
    102102        # this saves time because we don't need a complete parser ! 
    103103        minfile = self.minfile 
    104          
    105         # self.logdebug("--------------")     
    106         # for i in range(100) : 
    107         #     self.logdebug("%08i ==> 0x%02x ==> '%s'"  % (self.pos - 98 + i, ord(self.minfile[self.pos - 98 + i]), self.minfile[self.pos - 98 + i])) 
    108         # self.logdebug("--------------")     
    109              
    110         pos = self.pos - 2 
     104        pos = prevpos - 2 
    111105        while pos > 0 : # safety check : don't go back to far ! 
    112106            val = ord(minfile[pos]) 
     
    153147                        elif length == 2 :     
    154148                            startpos = pos + 5 
    155                             size = unpack(self.endianness + "H", self.minfile[pos+3:startpos])[0] 
     149                            size = unpack(self.unpackShort, self.minfile[pos+3:startpos])[0] 
    156150                        elif length == 4 :     
    157151                            startpos = pos + 7 
    158                             size = unpack(self.endianness + "I", self.minfile[pos+3:startpos])[0] 
     152                            size = unpack(self.unpackLong, self.minfile[pos+3:startpos])[0] 
    159153                        else :     
    160154                            raise pdlparser.PDLParserError, "Error on size at %s : %s" % (pos+2, length) 
     
    180174        return 0 
    181175         
    182     def endPage(self) :     
     176    def endPage(self, prevpos) :     
    183177        """Indicates the end of a page.""" 
    184         pos = self.pos 
     178        pos = prevpos 
    185179        pos3 = pos - 3 
    186180        minfile = self.minfile 
     
    191185            # of copies is an unsigned 16 bits integer 
    192186            try : 
    193                 self.pages[self.pagecount]["copies"] = unpack(self.endianness + "H", minfile[pos-5:pos3])[0] 
     187                self.pages[self.pagecount]["copies"] = unpack(self.unpackShort, minfile[pos-5:pos3])[0] 
    194188            except KeyError :     
    195189                self.logdebug("It looks like this PCLXL file is corrupted.") 
    196190        return 0 
    197191         
    198     def setColorSpace(self) :     
     192    def setColorSpace(self, prevpos) :     
    199193        """Changes the color space.""" 
    200         if self.minfile[self.pos-4:self.pos-1] == self.RGBColorSpace : 
     194        if self.minfile[prevpos-4:prevpos-1] == self.RGBColorSpace : 
    201195            self.iscolor = 1 
    202196        return 0 
    203197             
    204     def array_8(self) :     
     198    def array_8(self, prevpos) :     
    205199        """Handles byte arrays.""" 
    206         pos = self.pos 
     200        pos = prevpos 
    207201        datatype = self.minfile[pos] 
    208202        pos += 1 
    209203        length = self.tags[ord(datatype)] 
    210204        if callable(length) : 
    211             self.pos = pos 
    212             length = length() 
    213             pos = self.pos 
     205            length = length(pos) 
    214206        posl = pos + length 
    215         self.pos = posl 
    216207        if length == 1 :     
    217             return unpack("B", self.minfile[pos:posl])[0] 
     208            return 1 + length + unpack("B", self.minfile[pos:posl])[0] 
    218209        elif length == 2 :     
    219             return unpack(self.endianness + "H", self.minfile[pos:posl])[0] 
     210            return 1 + length + unpack(self.unpackShort, self.minfile[pos:posl])[0] 
    220211        elif length == 4 :     
    221             return unpack(self.endianness + "I", self.minfile[pos:posl])[0] 
     212            return 1 + length + unpack(self.unpackLong, self.minfile[pos:posl])[0] 
    222213        else :     
    223             raise pdlparser.PDLParserError, "Error on array size at %x" % self.pos 
    224          
    225     def array_16(self) :     
     214            raise pdlparser.PDLParserError, "Error on array size at %x" % prevpos 
     215         
     216    def array_16(self, prevpos) : 
    226217        """Handles byte arrays.""" 
    227         pos = self.pos 
     218        pos = prevpos 
    228219        datatype = self.minfile[pos] 
    229220        pos += 1 
    230221        length = self.tags[ord(datatype)] 
    231222        if callable(length) : 
    232             self.pos = pos 
    233             length = length() 
    234             pos = self.pos 
     223            length = length(pos) 
    235224        posl = pos + length 
    236         self.pos = posl 
    237225        if length == 1 :     
    238             return 2 * unpack("B", self.minfile[pos:posl])[0] 
     226            return 1 + length + 2 * unpack("B", self.minfile[pos:posl])[0] 
    239227        elif length == 2 :     
    240             return 2 * unpack(self.endianness + "H", self.minfile[pos:posl])[0] 
     228            return 1 + length + 2 * unpack(self.unpackShort, self.minfile[pos:posl])[0] 
    241229        elif length == 4 :     
    242             return 2 * unpack(self.endianness + "I", self.minfile[pos:posl])[0] 
     230            return 1 + length + 2 * unpack(self.unpackLong, self.minfile[pos:posl])[0] 
    243231        else :     
    244             raise pdlparser.PDLParserError, "Error on array size at %x" % self.pos 
    245          
    246     def array_32(self) :     
     232            raise pdlparser.PDLParserError, "Error on array size at %x" % prevpos 
     233         
     234    def array_32(self, prevpos) : 
    247235        """Handles byte arrays.""" 
    248         pos = self.pos 
     236        pos = prevpos 
    249237        datatype = self.minfile[pos] 
    250238        pos += 1 
    251239        length = self.tags[ord(datatype)] 
    252240        if callable(length) : 
    253             self.pos = pos 
    254             length = length() 
    255             pos = self.pos 
     241            length = length(pos) 
    256242        posl = pos + length 
    257         self.pos = posl 
    258243        if length == 1 :     
    259             return 4 * unpack("B", self.minfile[pos:posl])[0] 
     244            return 1 + length + 4 * unpack("B", self.minfile[pos:posl])[0] 
    260245        elif length == 2 :     
    261             return 4 * unpack(self.endianness + "H", self.minfile[pos:posl])[0] 
     246            return 1 + length + 4 * unpack(self.unpackShort, self.minfile[pos:posl])[0] 
    262247        elif length == 4 :     
    263             return 4 * unpack(self.endianness + "I", self.minfile[pos:posl])[0] 
     248            return 1 + length + 4 * unpack(self.unpackLong, self.minfile[pos:posl])[0] 
    264249        else :     
    265             raise pdlparser.PDLParserError, "Error on array size at %x" % self.pos 
    266          
    267     def embeddedDataSmall(self) : 
     250            raise pdlparser.PDLParserError, "Error on array size at %x" % prevpos 
     251         
     252    def embeddedDataSmall(self, prevpos) : 
    268253        """Handle small amounts of data.""" 
    269         pos = self.pos 
    270         length = ord(self.minfile[pos]) 
    271         self.pos = pos + 1 
    272         return length 
    273          
    274     def embeddedData(self) : 
     254        return 1 + ord(self.minfile[prevpos]) 
     255         
     256    def embeddedData(self, prevpos) : 
    275257        """Handle normal amounts of data.""" 
    276         pos = self.pos 
    277         pos4 = pos + 4 
    278         self.pos = pos4 
    279         return unpack(self.endianness + "I", self.minfile[pos:pos4])[0] 
    280          
    281     def littleEndian(self) :         
     258        return 4 + unpack(self.unpackLong, self.minfile[prevpos:prevpos+4])[0] 
     259         
     260    def littleEndian(self, prevpos) : 
    282261        """Toggles to little endianness.""" 
    283262        self.endianness = "<" # little endian 
     263        self.unpackShort = "<H" 
     264        self.unpackLong = "<I" 
    284265        return 0 
    285266         
    286     def bigEndian(self) :     
     267    def bigEndian(self, prevpos) : 
    287268        """Toggles to big endianness.""" 
    288269        self.endianness = ">" # big endian 
     270        self.unpackShort = ">H" 
     271        self.unpackLong = ">I" 
    289272        return 0 
    290273     
    291     def reservedForFutureUse(self) : 
     274    def reservedForFutureUse(self, prevpos) : 
    292275        """Outputs something when a reserved byte is encountered.""" 
    293         self.logdebug("Byte at %x is out of the PCLXL Protocol Class 2.0 Specification" % self.pos) 
     276        self.logdebug("Byte at %x is out of the PCLXL Protocol Class 2.0 Specification" % prevpos) 
    294277        return 0     
    295278         
    296     def passThrough(self) :     
    297         """Passthrough mode, as detailed in PCLXL Feature Reference Protocol Class 3.0 Supplement.""" 
    298         # TODO : do something here to skip the block. 
    299         self.logdebug("PassThrough marker detected at %x" % self.pos) 
    300         return 0 
    301          
    302     def x46_class3(self) :     
     279    def x46_class3(self, prevpos) : 
    303280        """Undocumented tag 0x46 in class 3.0 streams.""" 
    304         pos = self.pos 
     281        pos = prevpos 
    305282        minfile = self.minfile 
    306283        while pos > 0 : # safety check : don't go back to far ! 
     
    317294                    return unpack("B", self.minfile[pos:posl])[0] 
    318295                elif length == 2 :     
    319                     return unpack(self.endianness + "H", self.minfile[pos:posl])[0] 
     296                    return unpack(self.unpackShort, self.minfile[pos:posl])[0] 
    320297                elif length == 4 :     
    321                     return unpack(self.endianness + "I", self.minfile[pos:posl])[0] 
     298                    return unpack(self.unpackLong, self.minfile[pos:posl])[0] 
    322299                else :     
    323                     raise pdlparser.PDLParserError, "Error on size at %x" % self.pos 
     300                    raise pdlparser.PDLParserError, "Error on size at %x" % prevpos 
    324301            else :     
    325302                pos -= 1 
    326303        return 0     
    327304         
    328     def escape(self) :     
     305    def escape(self, prevpos) :     
    329306        """Handles the ESC code.""" 
    330         pos = endpos = self.pos 
     307        pos = endpos = prevpos 
    331308        minfile = self.minfile 
    332309        if minfile[pos : pos+8] == r"%-12345X" : 
     
    348325        return endpos - pos 
    349326         
    350     def skipKyoceraPrescribe(self) :     
     327    def skipKyoceraPrescribe(self, prevpos) : 
    351328        """Skips Kyocera Prescribe commands.""" 
    352         pos = self.pos - 1 
     329        pos = prevpos - 1 
    353330        minfile = self.minfile 
    354331        if minfile[pos:pos+3] == "!R!" : 
    355             while (pos - self.pos) < 1024 :   # This is a realistic upper bound, to avoid infinite loops 
     332            while (pos - prevpos) < 1024 :   # This is a realistic upper bound, to avoid infinite loops 
    356333                if (minfile[pos] == ";") and (minfile[pos-4:pos] == "EXIT") : 
    357334                    pos += 1 
    358335                    prescribe = self.prescribeStuff.setdefault(self.pagecount, []) 
    359                     prescribe.append(minfile[self.pos-1:pos]) 
    360                     self.logdebug("Prescribe commands : [%s]" % repr(minfile[self.pos-1:pos])) 
    361                     return (pos - self.pos) 
     336                    prescribe.append(minfile[prevpos-1:pos]) 
     337                    self.logdebug("Prescribe commands : [%s]" % repr(minfile[prevpos-1:pos])) 
     338                    return (pos - prevpos) 
    362339                pos += 1     
    363340        else : 
     
    393370                endian = ord(line[pos - 1]) 
    394371                if endian == 0x29 : 
    395                     self.littleEndian() 
     372                    self.littleEndian(0) 
    396373                elif endian == 0x28 :     
    397                     self.bigEndian() 
     374                    self.bigEndian(0) 
    398375                # elif endian == 0x27 : # TODO : This is the ESC code : parse it for PJL statements ! 
    399376                #  
     
    476453        self.tags[0xbe] = self.reservedForFutureUse # reserved 
    477454         
    478         self.tags[0xbf] = self.passThrough # From PCLXL Feature Reference Protocol Class 3.0 Supplement 
     455        # self.tags[0xbf] = self.passThrough # PassThrough mode should already be taken care of automatically 
    479456         
    480457        self.tags[0xc0] = 1 # ubyte 
     
    574551        self.escapedStuff = {}   # For escaped datas, mostly PJL commands 
    575552        self.prescribeStuff = {} # For Kyocera Prescribe commands 
    576         self.pos = pos = oldpos = 0 
     553        pos = oldpos = 0 
    577554        try : 
    578555            try : 
    579556                while 1 : 
    580557                    try : 
    581                         char = minfile[pos] 
     558                        tag = ord(minfile[pos]) 
    582559                    except OverflowError :     
    583560                        pos = oldpos + 1 
    584561                    pos += 1 
    585                     length = tags[ord(char)] 
     562                    length = tags[tag] 
    586563                    if length : 
    587564                        if callable(length) :     
    588                             self.pos = pos 
    589                             length = length() 
    590                             pos = self.pos 
     565                            length = length(pos) 
    591566                        oldpos = pos     
    592567                        pos += length