Changeset 1912

Show
Ignore:
Timestamp:
11/13/04 21:52:26 (20 years ago)
Author:
jalet
Message:

Heavy work done on PCL3/4/5 and PCLXL job analyzis

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/pykota/pdlanalyzer.py

    r1743 r1912  
    2222# 
    2323# $Log$ 
     24# Revision 1.43  2004/11/13 20:52:26  jalet 
     25# Heavy work done on PCL3/4/5 and PCLXL job analyzis 
     26# 
    2427# Revision 1.42  2004/09/24 21:19:48  jalet 
    2528# Did a pass of PyChecker 
     
    179182     
    180183class PostScriptAnalyzer : 
     184    """A class to parse PostScript documents.""" 
    181185    def __init__(self, infile) : 
    182186        """Initialize PostScript Analyzer.""" 
     
    244248         
    245249class PDFAnalyzer : 
     250    """A class to parse PDF documents.""" 
    246251    def __init__(self, infile) : 
    247252        """Initialize PDF Analyzer.""" 
     
    257262         
    258263class ESCP2Analyzer : 
     264    """A class to parse ESC/P2 documents.""" 
    259265    def __init__(self, infile) : 
    260266        """Initialize ESC/P2 Analyzer.""" 
     
    297303         
    298304class PCLAnalyzer : 
     305    """A class to parse PCL3, PCL4, PCL5 documents.""" 
     306    mediasizes = {  # ESC&l####A 
     307                    0 : "Default", 
     308                    1 : "Executive", 
     309                    2 : "Letter", 
     310                    3 : "Legal", 
     311                    6 : "Ledger",  
     312                    25 : "A5", 
     313                    26 : "A4", 
     314                    27 : "A3", 
     315                    45 : "JB5", 
     316                    46 : "JB4", 
     317                    71 : "HagakiPostcard", 
     318                    72 : "OufukuHagakiPostcard", 
     319                    80 : "MonarchEnvelope", 
     320                    81 : "COM10Envelope", 
     321                    90 : "DLEnvelope", 
     322                    91 : "C5Envelope", 
     323                    100 : "B5Envelope", 
     324                    101 : "Custom", 
     325                 }    
     326                  
     327    mediasources = { # ESC&l####H 
     328                     0 : "Default", 
     329                     1 : "Main", 
     330                     2 : "Manual", 
     331                     3 : "ManualEnvelope", 
     332                     4 : "Alternate", 
     333                     5 : "OptionalLarge", 
     334                     6 : "EnvelopeFeeder", 
     335                     7 : "Auto", 
     336                     8 : "Tray1", 
     337                   } 
     338                    
     339    orientations = { # ESC&l####O 
     340                     0 : "Portrait", 
     341                     1 : "Landscape", 
     342                     2 : "ReversePortrait", 
     343                     3 : "ReverseLandscape", 
     344                   } 
     345                    
     346    mediatypes = { # ESC&l####M 
     347                     0 : "Plain", 
     348                     1 : "Bond", 
     349                     2 : "Special", 
     350                     3 : "Glossy", 
     351                     4 : "Transparent", 
     352                   } 
     353                    
     354                    
    299355    def __init__(self, infile) : 
    300356        """Initialize PCL Analyzer.""" 
    301357        self.infile = infile 
     358         
     359    def setPageDict(self, pages, number, attribute, value) : 
     360        """Initializes a page dictionnary.""" 
     361        dict = pages.setdefault(number, { "copies" : 1, "mediasource" : "Main", "mediasize" : "Default", "mediatype" : "Plain", "orientation" : "Portrait"}) 
     362        dict[attribute] = value 
    302363         
    303364    def getJobSize(self) :      
     
    332393                     ")s" : "W",  
    333394                     "&p" : "X",  
    334                      "&l" : "XH", 
     395                     # "&l" : "XHAOM",  # treated specially 
    335396                     "&a" : "G", # TODO : 0 means next side, 1 front side, 2 back side 
    336397                     "*g" : "W", 
     
    339400                   }   
    340401        pagecount = resets = ejects = backsides = startgfx = endgfx = 0 
    341         starb = ispcl3 = 0 
     402        starb = ampl = ispcl3 = 0 
    342403        tag = None 
    343         copies = {} 
     404        pages = {} 
    344405        pos = 0 
    345406        try : 
     
    349410                    pagecount += 1 
    350411                elif char == "\033" :     
    351                     starb = 0 
     412                    starb = ampl = 0 
    352413                    # 
    353414                    #     <ESC>*b###y#m###v###w... -> PCL3 raster graphics 
     
    369430                    #     <ESC>&a2G -> Back side when duplex mode as generated by rastertohp 
    370431                    #     <ESC>*g###W -> Needed for planes in PCL3 output 
    371                     #     <ESC>&l0H -> Eject if NumPlanes > 1, as generated by rastertohp 
     432                    #     <ESC>&l###H (or only 0 ?) -> Eject if NumPlanes > 1, as generated by rastertohp. Also defines mediasource 
     433                    #     <ESC>&l###A -> mediasize 
     434                    #     <ESC>&l###O -> orientation 
     435                    #     <ESC>&l###M -> mediatype 
    372436                    # 
    373437                    tagstart = minfile[pos] ; pos += 1 
     
    380444                        starb = 1 
    381445                        tagend = "VW" 
     446                    elif tag == "&l" :     
     447                        ampl = 1 
     448                        tagend = "XHAOM" 
    382449                    else :     
    383450                        try : 
     
    393460                        size = (size * 10) + int(char)     
    394461                    if char in tagend :     
    395                         if (tag == "&l") and (char == "X") : # copies for current page 
    396                             copies[pagecount] = size 
    397                         elif (tag == "&l") and (char == "H") and (size == 0) :     
    398                             ejects += 1         # Eject  
    399                         elif (tag == "*r") : 
     462                        if tag == "&l" : 
     463                            if char == "X" :  
     464                                self.setPageDict(pages, pagecount, "copies", size) 
     465                            elif char == "H" : 
     466                                self.setPageDict(pages, pagecount, "mediasource", self.mediasources.get(size, str(size))) 
     467                                ejects += 1  
     468                            elif char == "A" : 
     469                                self.setPageDict(pages, pagecount, "mediasize", self.mediasizes.get(size, str(size))) 
     470                            elif char == "O" : 
     471                                self.setPageDict(pages, pagecount, "orientation", self.orientations.get(size, str(size))) 
     472                            elif char == "M" : 
     473                                self.setPageDict(pages, pagecount, "mediatype", self.mediatypes.get(size, str(size))) 
     474                        elif tag == "*r" : 
    400475                            # Special tests for PCL3 
    401476                            if (char == "s") and size : 
     
    433508                            ispcl3 = 1  # certainely a PCL3 document 
    434509                            pos -= 1    # fix position : we were ahead 
     510                    elif ampl :         
     511                        # special handling of PCL3 in which  
     512                        # &l introduces combined ESCape sequences 
     513                        size = 0 
     514                        while 1 : 
     515                            char = minfile[pos] ; pos += 1 
     516                            if not char.isdigit() : 
     517                                break 
     518                            size = (size * 10) + int(char)     
     519                        if char in ("a", "o", "h", "m") :     
     520                            ispcl3 = 1  # certainely a PCL3 document 
     521                            pos -= 1    # fix position : we were ahead 
     522                            if char == "h" : 
     523                                self.setPageDict(pages, pagecount, "mediasource", self.mediasources.get(size, str(size))) 
     524                            elif char == "a" : 
     525                                self.setPageDict(pages, pagecount, "mediasize", self.mediasizes.get(size, str(size))) 
     526                            elif char == "o" : 
     527                                self.setPageDict(pages, pagecount, "orientation", self.orientations.get(size, str(size))) 
     528                            elif char == "m" : 
     529                                self.setPageDict(pages, pagecount, "mediatype", self.mediatypes.get(size, str(size))) 
    435530        except IndexError : # EOF ? 
    436531            minfile.close() # reached EOF 
     
    456551        for pnum in range(pagecount) : 
    457552            # if no number of copies defined, take the preceding one else the one set before any page else 1. 
    458             nb = copies.get(pnum, copies.get(pnum-1, copies.get(0, 1))) 
    459             pagecount += (nb - 1) 
     553            page = pages.get(pnum, pages.get(pnum - 1, pages.get(0, { "copies" : 1 }))) 
     554            pagecount += (page["copies"] - 1) 
    460555             
    461556        # in PCL3 files, there's one Start Gfx tag per page 
     
    467562            elif endgfx :     
    468563                pagecount = endgfx 
     564                 
     565        #for pnum in range(pagecount) : 
     566        #    # if no number of copies defined, take the preceding one else the one set before any page else 1. 
     567        #    page = pages.get(pnum, pages.get(pnum - 1, pages.get(0, { "copies" : 1, "mediasource" : "Main", "mediasize" : "Default", "mediatype" : "Plain", "orientation" : "Portrait"}))) 
     568        #    print "%s*%s*%s*%s*%s" % (page["copies"], page["mediatype"], page["mediasize"], page["orientation"], page["mediasource"]) 
    469569             
    470570        return pagecount 
    471571         
    472572class PCLXLAnalyzer : 
     573    """A class to parse PCL6 (aka XL) documents.""" 
     574    mediasizes = {  
     575                    0 : "Letter", 
     576                    1 : "Legal", 
     577                    2 : "A4", 
     578                    3 : "Executive", 
     579                    4 : "Ledger", 
     580                    5 : "A3", 
     581                    6 : "COM10Envelope", 
     582                    7 : "MonarchEnvelope", 
     583                    8 : "C5Envelope", 
     584                    9 : "DLEnvelope", 
     585                    10 : "JB4", 
     586                    11 : "JB5", 
     587                    12 : "B5Envelope", 
     588                    14 : "JPostcard", 
     589                    15 : "JDoublePostcard", 
     590                    16 : "A5", 
     591                    17 : "A6", 
     592                    18 : "JB6", 
     593                 }    
     594                  
     595    mediasources = {              
     596                     0 : "Default", 
     597                     1 : "Auto", 
     598                     2 : "Manual", 
     599                     3 : "MultiPurpose", 
     600                     4 : "UpperCassette", 
     601                     5 : "LowerCassette", 
     602                     6 : "EnvelopeTray", 
     603                     7 : "ThirdCassette", 
     604                   } 
     605                    
     606    orientations = {                
     607                     0 : "Portrait", 
     608                     1 : "Landscape", 
     609                     2 : "ReversePortrait", 
     610                     3 : "ReverseLandscape", 
     611                   } 
     612                    
    473613    def __init__(self, infile) : 
    474614        """Initialize PCLXL Analyzer.""" 
     
    487627                elif endian == 0x28 :     
    488628                    self.bigEndian() 
    489                 # elif endian == 0x27 : TODO : What can we do here ?     
     629                # elif endian == 0x27 : # TODO : This is the ESC code : parse it for PJL statements ! 
    490630                #  
    491631                else :     
     
    540680             
    541681    def beginPage(self) : 
    542         """Indicates the beginning of a new page.""" 
     682        """Indicates the beginning of a new page, and extracts media information.""" 
    543683        self.pagecount += 1 
     684         
     685        # Default values 
     686        mediatypelabel = "Plain" 
     687        mediasourcelabel = "Main" 
     688        mediasizelabel = "Default" 
     689        orientationlabel = "Portrait" 
     690         
     691        # Now go upstream to decode media type, size, source, and orientation 
     692        # this saves time because we don't need a complete parser ! 
     693        minfile = self.minfile 
     694        pos = self.pos - 2 
     695        while pos > 0 : # safety check : don't go back to far ! 
     696            val = ord(minfile[pos]) 
     697            if val in (0x44, 0x48, 0x41) : # if previous endPage or openDataSource or beginSession (first page) 
     698                break 
     699            if val == 0x26 :     
     700                mediasource = ord(minfile[pos - 2]) 
     701                mediasourcelabel = self.mediasources.get(mediasource, str(mediasource)) 
     702                pos = pos - 4 
     703            elif val == 0x25 : 
     704                mediasize = ord(minfile[pos - 2]) 
     705                mediasizelabel = self.mediasizes.get(mediasize, str(mediasize)) 
     706                pos = pos - 4 
     707            elif val == 0x28 :     
     708                orientation = ord(minfile[pos - 2]) 
     709                orienationlabel = self.orientations.get(orientation, str(orientation)) 
     710                pos = pos - 4 
     711            elif val == 0x27 :     
     712                savepos = pos 
     713                pos = pos - 1 
     714                while pos > 0 : # safety check : don't go back to far ! 
     715                    val = ord(minfile[pos]) 
     716                    pos -= 1     
     717                    if val == 0xc8 : 
     718                        break 
     719                mediatypelabel = minfile[pos:savepos] # TODO : INCORRECT, WE HAVE TO STRIP OUT THE UBYTE ARRAY'S LENGTH !!! 
     720            # else : TODO : CUSTOM MEDIA SIZE AND UNIT !  
     721            else :     
     722                pos = pos - 2   # ignored 
     723        self.pages[self.pagecount] = { "copies" : 1,  
     724                                       "orientation" : orientationlabel,  
     725                                       "mediatype" : mediatypelabel,  
     726                                       "mediasize" : mediasizelabel, 
     727                                       "mediasource" : mediasourcelabel, 
     728                                     }  
    544729        return 0 
    545730         
     
    549734        minfile = self.minfile 
    550735        if (ord(minfile[pos-3]) == 0xf8) and (ord(minfile[pos-2]) == 0x31) : 
    551             # The EndPage operator is preceded by a PageCopies attribute 
     736            # The EndPage operator may be preceded by a PageCopies attribute 
    552737            # So set number of copies for current page. 
    553738            # From what I read in PCLXL documentation, the number 
    554739            # of copies is an unsigned 16 bits integer 
    555             self.copies[self.pagecount] = unpack(self.endianness + "H", minfile[pos-5:pos-3])[0] 
     740            self.pages[self.pagecount]["copies"] = unpack(self.endianness + "H", minfile[pos-5:pos-3])[0] 
    556741        return 0 
    557742         
     
    655840        """ 
    656841        infileno = self.infile.fileno() 
    657         self.copies = {} 
     842        self.pages = {} 
    658843        self.minfile = minfile = mmap.mmap(infileno, os.fstat(infileno)[6], prot=mmap.PROT_READ, flags=mmap.MAP_SHARED) 
    659844        tags = self.tags 
     
    682867            # but the formula below is still correct : we want  
    683868            # to decrease the total number of pages in this case. 
    684             self.pagecount += (self.copies.get(pnum, 1) - 1) 
     869            page = self.pages.get(pnum, 1) 
     870            copies = page["copies"] 
     871            self.pagecount += (copies - 1) 
     872            # print "%s*%s*%s*%s*%s" % (copies, page["mediatype"], page["mediasize"], page["orientation"], page["mediasource"]) 
    685873             
    686874        return self.pagecount