Changeset 1572

Show
Ignore:
Timestamp:
06/26/04 17:31:00 (20 years ago)
Author:
jalet
Message:

mmap reintroduced in PCL5 parser

Location:
pykota/trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/NEWS

    r1570 r1572  
    2424    - 1.19alpha27 : 
    2525     
     26        - Reintroduced the use of mmap in PCL5 parser : this speedups 
     27          PCL5 parsing by almost 4 times. 
     28          This 4x with the 3x below give us in fact a twelvefold increase 
     29          in performance for PCL5 parsing ! 
     30           
    2631        - The Python accelerator Psyco is now used if available 
    2732          in the generic PDL parser : it speedups PCL5 parsing by 
    28           almost three times automagically. 
     33          almost three times automagically.  
    2934           
    3035    - 1.19alpha26 : 
  • pykota/trunk/pykota/pdlanalyzer.py

    r1570 r1572  
    2222# 
    2323# $Log$ 
     24# Revision 1.16  2004/06/26 15:31:00  jalet 
     25# mmap reintroduced in PCL5 parser 
     26# 
    2427# Revision 1.15  2004/06/26 14:14:31  jalet 
    2528# Now uses Psyco if it is available 
     
    7780import struct 
    7881import tempfile 
    79 import popen2 
     82import mmap 
    8083     
    8184KILOBYTE = 1024     
     
    122125        self.infile = infile 
    123126         
    124     def skip(self, nb) :     
    125         """Reads a new datablock.""" 
    126         newpos = self.pos + nb 
    127         if newpos >= self.len : 
    128             oldlen = self.len 
    129             self.data = self.infile.read(MEGABYTE) 
    130             self.len = len(self.data) 
    131             if not self.len : 
    132                 return 
    133             self.pos = newpos - oldlen 
    134         else :     
    135             self.pos = newpos 
    136          
    137     def readone(self) : 
    138         """Reads a new byte.""" 
    139         if self.pos < self.len : 
    140             char = self.data[self.pos] 
    141         else :     
    142             self.data = self.infile.read(MEGABYTE) 
    143             self.len = len(self.data) 
    144             self.pos = 0 
    145             if not self.len :     
    146                 return 
    147             char = self.data[0] 
    148         self.pos += 1     
    149         return char 
    150          
    151127    def getJobSize(self) :      
    152128        """Count pages in a PCL5 document.""" 
     
    165141        # http://h20000.www2.hp.com/bc/docs/support/SupportManual/bpl13205/bpl13205.pdf  
    166142        # 
     143        infileno = self.infile.fileno() 
     144        minfile = mmap.mmap(infileno, os.fstat(infileno).st_size, access=mmap.ACCESS_READ) 
    167145        tagsends = { "&n" : "W",  
    168146                     "&b" : "W",  
     
    180158                     "&a" : "G", 
    181159                   }   
    182         self.data = []              
    183         self.pos = self.len = 0 
    184160        pagecount = resets = ejects = backsides = 0 
    185161        tag = None 
    186162        copies = {} 
    187         while 1 : 
    188             char = self.readone() 
    189             if not char :       # EOF ? 
    190                 break    
    191             if char == "\014" :     
    192                 pagecount += 1 
    193             elif char == "\033" :     
    194                 # 
    195                 #     <ESC>*b###W -> Start of a raster data row/block 
    196                 #     <ESC>*b###V -> Start of a raster data plane 
    197                 #     <ESC>*c###W -> Start of a user defined pattern 
    198                 #     <ESC>*i###W -> Start of a viewing illuminant block 
    199                 #     <ESC>*l###W -> Start of a color lookup table 
    200                 #     <ESC>*m###W -> Start of a download dither matrix block 
    201                 #     <ESC>*v###W -> Start of a configure image data block 
    202                 #     <ESC>(s###W -> Start of a characters description block 
    203                 #     <ESC>)s###W -> Start of a fonts description block 
    204                 #     <ESC>(f###W -> Start of a symbol set block 
    205                 #     <ESC>&b###W -> Start of configuration data block 
    206                 #     <ESC>&l###X -> Number of copies for current page 
    207                 #     <ESC>&n###W -> Starts an alphanumeric string ID block 
    208                 #     <ESC>&p###X -> Start of a non printable characters block 
    209                 #     <ESC>&a2G -> Back side when duplex mode as generated by rastertohp 
    210                 #     <ESC>&l0H -> Eject if NumPlanes > 1, as generated by rastertohp 
    211                 # 
    212                 tagstart = self.readone() 
    213                 if tagstart in "E9=YZ" : # one byte PCL tag 
    214                     if tagstart == "E" : 
    215                         resets += 1 
    216                     continue             # skip to next tag 
    217                 tag = tagstart + self.readone() 
    218                 try : 
    219                     tagend = tagsends[tag] 
    220                 except KeyError :     
    221                     pass    # Unsupported PCL tag 
    222                 else :     
    223                     # Now read the numeric argument 
    224                     size = 0 
    225                     while 1 : 
    226                         char = self.readone() 
    227                         if not char.isdigit() : 
    228                             break 
    229                         size = (size * 10) + int(char)     
    230                     if char in tagend :     
    231                         if (tag == "&l") and (char == "X") : # copies for current page 
    232                             copies[pagecount] = size 
    233                         elif (tag == "&l") and (char == "H") and (size == 0) :     
    234                             ejects += 1         # Eject  
    235                         elif (tag == "&a") and (size == 2) : 
    236                             backsides += 1      # Back side in duplex mode 
    237                         else :     
    238                             # doing a read will prevent the seek  
    239                             # for unseekable streams.  
    240                             # we just ignore the block anyway. 
    241                             if tag == "&n" :  
    242                                 # we have to take care of the operation id byte 
    243                                 # which is before the string itself 
    244                                 size += 1 
    245                             self.skip(size) 
     163        pos = 0 
     164        try : 
     165            while 1 : 
     166                char = minfile[pos] ; pos += 1 
     167                if char == "\014" :     
     168                    pagecount += 1 
     169                elif char == "\033" :     
     170                    # 
     171                    #     <ESC>*b###W -> Start of a raster data row/block 
     172                    #     <ESC>*b###V -> Start of a raster data plane 
     173                    #     <ESC>*c###W -> Start of a user defined pattern 
     174                    #     <ESC>*i###W -> Start of a viewing illuminant block 
     175                    #     <ESC>*l###W -> Start of a color lookup table 
     176                    #     <ESC>*m###W -> Start of a download dither matrix block 
     177                    #     <ESC>*v###W -> Start of a configure image data block 
     178                    #     <ESC>(s###W -> Start of a characters description block 
     179                    #     <ESC>)s###W -> Start of a fonts description block 
     180                    #     <ESC>(f###W -> Start of a symbol set block 
     181                    #     <ESC>&b###W -> Start of configuration data block 
     182                    #     <ESC>&l###X -> Number of copies for current page 
     183                    #     <ESC>&n###W -> Starts an alphanumeric string ID block 
     184                    #     <ESC>&p###X -> Start of a non printable characters block 
     185                    #     <ESC>&a2G -> Back side when duplex mode as generated by rastertohp 
     186                    #     <ESC>&l0H -> Eject if NumPlanes > 1, as generated by rastertohp 
     187                    # 
     188                    tagstart = minfile[pos] ; pos += 1 
     189                    if tagstart in "E9=YZ" : # one byte PCL tag 
     190                        if tagstart == "E" : 
     191                            resets += 1 
     192                        continue             # skip to next tag 
     193                    tag = tagstart + minfile[pos] ; pos += 1 
     194                    try : 
     195                        tagend = tagsends[tag] 
     196                    except KeyError :     
     197                        pass    # Unsupported PCL tag 
     198                    else :     
     199                        # Now read the numeric argument 
     200                        size = 0 
     201                        while 1 : 
     202                            char = minfile[pos] ; pos += 1 
     203                            if not char.isdigit() : 
     204                                break 
     205                            size = (size * 10) + int(char)     
     206                        if char in tagend :     
     207                            if (tag == "&l") and (char == "X") : # copies for current page 
     208                                copies[pagecount] = size 
     209                            elif (tag == "&l") and (char == "H") and (size == 0) :     
     210                                ejects += 1         # Eject  
     211                            elif (tag == "&a") and (size == 2) : 
     212                                backsides += 1      # Back side in duplex mode 
     213                            else :     
     214                                # we just ignore the block. 
     215                                if tag == "&n" :  
     216                                    # we have to take care of the operation id byte 
     217                                    # which is before the string itself 
     218                                    size += 1 
     219                                pos += size     
     220        except IndexError : # EOF ? 
     221            minfile.close() # reached EOF 
    246222                             
    247223        # if pagecount is still 0, we will use the number