Index: /pkpgcounter/trunk/pkpgpdls/pcl345.py
===================================================================
--- /pkpgcounter/trunk/pkpgpdls/pcl345.py (revision 303)
+++ /pkpgcounter/trunk/pkpgpdls/pcl345.py (revision 305)
@@ -25,4 +25,5 @@
 import os
 import mmap
+from struct import unpack
 
 import pdlparser
@@ -84,5 +85,6 @@
            (self.firstblock.startswith("\033*rbC") and (not self.lastblock[-3:] == "\f\033@")) or \
            self.firstblock.startswith("\033%8\033") or \
-           (self.firstblock.find("\033%-12345X") != -1) :
+           (self.firstblock.find("\033%-12345X") != -1) or \
+           (self.firstblock.startswith(chr(0xcd)+chr(0xca)) and self.firstblock.find("\033E\033")) :
             self.logdebug("DEBUG: Input file is in the PCL3/4/5 format.")
             return 1
@@ -133,4 +135,8 @@
                      # "*b" : "VW", # treated specially because it occurs very often
                    }  
+        irmarker = chr(0xcd) + chr(0xca) # Marker for Canon ImageRunner printers
+        irmarker2 = chr(0x10) + chr(0x02)
+        wasirmarker = 0
+        hasirmarker = (minfile[:2] == (irmarker))
         pagecount = resets = ejects = backsides = startgfx = endgfx = 0
         starb = ampl = ispcl3 = escstart = 0
@@ -143,150 +149,160 @@
         try :
             while 1 :
-                char = minfile[pos] ; pos += 1
-                if char == "\014" :    
-                    pagecount += 1
-                elif char == "\033" :    
-                    starb = ampl = 0
-                    if minfile[pos : pos+8] == r"%-12345X" :
-                        endpos = pos + 9
-                        quotes = 0
-                        while (minfile[endpos] not in endmark) and \
-                              ((minfile[endpos] < asciilimit) or (quotes % 2)) :
-                            if minfile[endpos] == '"' :
-                                quotes += 1
-                            endpos += 1
-                        self.setPageDict(pages, pagecount, "escaped", minfile[pos : endpos])
-                        pos += (endpos - pos)
-                    else :
-                        #
-                        #     <ESC>*b###y#m###v###w... -> PCL3 raster graphics
-                        #     <ESC>*b###W -> Start of a raster data row/block
-                        #     <ESC>*b###V -> Start of a raster data plane
-                        #     <ESC>*c###W -> Start of a user defined pattern
-                        #     <ESC>*i###W -> Start of a viewing illuminant block
-                        #     <ESC>*l###W -> Start of a color lookup table
-                        #     <ESC>*m###W -> Start of a download dither matrix block
-                        #     <ESC>*v###W -> Start of a configure image data block
-                        #     <ESC>*r1A -> Start Gfx 
-                        #     <ESC>(s###W -> Start of a characters description block
-                        #     <ESC>)s###W -> Start of a fonts description block
-                        #     <ESC>(f###W -> Start of a symbol set block
-                        #     <ESC>&b###W -> Start of configuration data block
-                        #     <ESC>&l###X -> Number of copies for current page
-                        #     <ESC>&n###W -> Starts an alphanumeric string ID block
-                        #     <ESC>&p###X -> Start of a non printable characters block
-                        #     <ESC>&a2G -> Back side when duplex mode as generated by rastertohp
-                        #     <ESC>*g###W -> Needed for planes in PCL3 output
-                        #     <ESC>&l###H (or only 0 ?) -> Eject if NumPlanes > 1, as generated by rastertohp. Also defines mediasource
-                        #     <ESC>&l###A -> mediasize
-                        #     <ESC>&l###O -> orientation
-                        #     <ESC>&l###M -> mediatype
-                        #     <ESC>*t###R -> gfx resolution
-                        #
-                        tagstart = minfile[pos] ; pos += 1
-                        if tagstart in "E9=YZ" : # one byte PCL tag
-                            if tagstart == "E" :
-                                resets += 1
-                            continue             # skip to next tag
-                        tag = tagstart + minfile[pos] ; pos += 1
-                        if tag == "*b" : 
-                            starb = 1
-                            tagend = "VW"
-                        elif tag == "&l" :    
-                            ampl = 1
-                            tagend = "XHAOM"
-                        else :    
-                            try :
-                                tagend = tagsends[tag]
-                            except KeyError :    
-                                continue # Unsupported PCL tag
-                        # Now read the numeric argument
-                        size = 0
-                        while 1 :
-                            char = minfile[pos] ; pos += 1
-                            if not char.isdigit() :
-                                break
-                            size = (size * 10) + int(char)    
-                        if char in tagend :    
-                            if tag == "&l" :
-                                if char == "X" : 
-                                    self.setPageDict(pages, pagecount, "copies", size)
-                                elif char == "H" :
+                if hasirmarker and (minfile[pos:pos+2] == irmarker) :
+                    codop = minfile[pos+2:pos+4]
+                    # self.logdebug("Marker at 0x%08x     (%s)" % (pos, wasirmarker))
+                    length = unpack(">H", minfile[pos+8:pos+10])[0]
+                    pos += 20
+                    if codop != irmarker2 :
+                        pos += length
+                    wasirmarker = 1    
+                else :        
+                    wasirmarker = 0
+                    char = minfile[pos] ; pos += 1
+                    if char == "\014" :    
+                        pagecount += 1
+                    elif char == "\033" :    
+                        starb = ampl = 0
+                        if minfile[pos : pos+8] == r"%-12345X" :
+                            endpos = pos + 9
+                            quotes = 0
+                            while (minfile[endpos] not in endmark) and \
+                                  ((minfile[endpos] < asciilimit) or (quotes % 2)) :
+                                if minfile[endpos] == '"' :
+                                    quotes += 1
+                                endpos += 1
+                            self.setPageDict(pages, pagecount, "escaped", minfile[pos : endpos])
+                            pos += (endpos - pos)
+                        else :
+                            #
+                            #     <ESC>*b###y#m###v###w... -> PCL3 raster graphics
+                            #     <ESC>*b###W -> Start of a raster data row/block
+                            #     <ESC>*b###V -> Start of a raster data plane
+                            #     <ESC>*c###W -> Start of a user defined pattern
+                            #     <ESC>*i###W -> Start of a viewing illuminant block
+                            #     <ESC>*l###W -> Start of a color lookup table
+                            #     <ESC>*m###W -> Start of a download dither matrix block
+                            #     <ESC>*v###W -> Start of a configure image data block
+                            #     <ESC>*r1A -> Start Gfx 
+                            #     <ESC>(s###W -> Start of a characters description block
+                            #     <ESC>)s###W -> Start of a fonts description block
+                            #     <ESC>(f###W -> Start of a symbol set block
+                            #     <ESC>&b###W -> Start of configuration data block
+                            #     <ESC>&l###X -> Number of copies for current page
+                            #     <ESC>&n###W -> Starts an alphanumeric string ID block
+                            #     <ESC>&p###X -> Start of a non printable characters block
+                            #     <ESC>&a2G -> Back side when duplex mode as generated by rastertohp
+                            #     <ESC>*g###W -> Needed for planes in PCL3 output
+                            #     <ESC>&l###H (or only 0 ?) -> Eject if NumPlanes > 1, as generated by rastertohp. Also defines mediasource
+                            #     <ESC>&l###A -> mediasize
+                            #     <ESC>&l###O -> orientation
+                            #     <ESC>&l###M -> mediatype
+                            #     <ESC>*t###R -> gfx resolution
+                            #
+                            tagstart = minfile[pos] ; pos += 1
+                            if tagstart in "E9=YZ" : # one byte PCL tag
+                                if tagstart == "E" :
+                                    resets += 1
+                                continue             # skip to next tag
+                            tag = tagstart + minfile[pos] ; pos += 1
+                            if tag == "*b" : 
+                                starb = 1
+                                tagend = "VW"
+                            elif tag == "&l" :    
+                                ampl = 1
+                                tagend = "XHAOM"
+                            else :    
+                                try :
+                                    tagend = tagsends[tag]
+                                except KeyError :    
+                                    continue # Unsupported PCL tag
+                            # Now read the numeric argument
+                            size = 0
+                            while 1 :
+                                char = minfile[pos] ; pos += 1
+                                if not char.isdigit() :
+                                    break
+                                size = (size * 10) + int(char)    
+                            if char in tagend :    
+                                if tag == "&l" :
+                                    if char == "X" : 
+                                        self.setPageDict(pages, pagecount, "copies", size)
+                                    elif char == "H" :
+                                        self.setPageDict(pages, pagecount, "mediasource", self.mediasources.get(size, str(size)))
+                                        mediasourcecount += 1
+                                        ejects += 1 
+                                    elif char == "A" :
+                                        self.setPageDict(pages, pagecount, "mediasize", self.mediasizes.get(size, str(size)))
+                                        mediasizecount += 1
+                                    elif char == "O" :
+                                        self.setPageDict(pages, pagecount, "orientation", self.orientations.get(size, str(size)))
+                                        orientationcount += 1
+                                    elif char == "M" :
+                                        self.setPageDict(pages, pagecount, "mediatype", self.mediatypes.get(size, str(size)))
+                                        mediatypecount += 1
+                                elif tag == "*r" :
+                                    # Special tests for PCL3
+                                    if (char == "s") and size :
+                                        while 1 :
+                                            char = minfile[pos] ; pos += 1
+                                            if char == "A" :
+                                                break
+                                    elif (char == "b") and (minfile[pos] == "C") and not size :
+                                        ispcl3 = 1 # Certainely a PCL3 file
+                                    startgfx += (char == "A") and (minfile[pos - 2] in ("0", "1", "2", "3")) # Start Gfx
+                                    endgfx += (not size) and (char in ("C", "B")) # End Gfx
+                                elif tag == "*t" :    
+                                    escstart += 1
+                                elif (tag == "&a") and (size == 2) :
+                                    # We are on the backside, so mark current page as duplex
+                                    self.setPageDict(pages, pagecount, "duplex", 1)
+                                    backsides += 1      # Back side in duplex mode
+                                else :    
+                                    # we just ignore the block.
+                                    if tag == "&n" : 
+                                        # we have to take care of the operation id byte
+                                        # which is before the string itself
+                                        size += 1
+                                    pos += size    
+                    else :                            
+                        if starb :
+                            # special handling of PCL3 in which 
+                            # *b introduces combined ESCape sequences
+                            size = 0
+                            while 1 :
+                                char = minfile[pos] ; pos += 1
+                                if not char.isdigit() :
+                                    break
+                                size = (size * 10) + int(char)    
+                            if char in ("w", "v") :    
+                                ispcl3 = 1  # certainely a PCL3 document
+                                pos += size - 1
+                            elif char in ("y", "m") :    
+                                ispcl3 = 1  # certainely a PCL3 document
+                                pos -= 1    # fix position : we were ahead
+                        elif ampl :        
+                            # special handling of PCL3 in which 
+                            # &l introduces combined ESCape sequences
+                            size = 0
+                            while 1 :
+                                char = minfile[pos] ; pos += 1
+                                if not char.isdigit() :
+                                    break
+                                size = (size * 10) + int(char)    
+                            if char in ("a", "o", "h", "m") :    
+                                ispcl3 = 1  # certainely a PCL3 document
+                                pos -= 1    # fix position : we were ahead
+                                if char == "h" :
                                     self.setPageDict(pages, pagecount, "mediasource", self.mediasources.get(size, str(size)))
                                     mediasourcecount += 1
-                                    ejects += 1 
-                                elif char == "A" :
+                                elif char == "a" :
                                     self.setPageDict(pages, pagecount, "mediasize", self.mediasizes.get(size, str(size)))
                                     mediasizecount += 1
-                                elif char == "O" :
+                                elif char == "o" :
                                     self.setPageDict(pages, pagecount, "orientation", self.orientations.get(size, str(size)))
                                     orientationcount += 1
-                                elif char == "M" :
+                                elif char == "m" :
                                     self.setPageDict(pages, pagecount, "mediatype", self.mediatypes.get(size, str(size)))
                                     mediatypecount += 1
-                            elif tag == "*r" :
-                                # Special tests for PCL3
-                                if (char == "s") and size :
-                                    while 1 :
-                                        char = minfile[pos] ; pos += 1
-                                        if char == "A" :
-                                            break
-                                elif (char == "b") and (minfile[pos] == "C") and not size :
-                                    ispcl3 = 1 # Certainely a PCL3 file
-                                startgfx += (char == "A") and (minfile[pos - 2] in ("0", "1", "2", "3")) # Start Gfx
-                                endgfx += (not size) and (char in ("C", "B")) # End Gfx
-                            elif tag == "*t" :    
-                                escstart += 1
-                            elif (tag == "&a") and (size == 2) :
-                                # We are on the backside, so mark current page as duplex
-                                self.setPageDict(pages, pagecount, "duplex", 1)
-                                backsides += 1      # Back side in duplex mode
-                            else :    
-                                # we just ignore the block.
-                                if tag == "&n" : 
-                                    # we have to take care of the operation id byte
-                                    # which is before the string itself
-                                    size += 1
-                                pos += size    
-                else :                            
-                    if starb :
-                        # special handling of PCL3 in which 
-                        # *b introduces combined ESCape sequences
-                        size = 0
-                        while 1 :
-                            char = minfile[pos] ; pos += 1
-                            if not char.isdigit() :
-                                break
-                            size = (size * 10) + int(char)    
-                        if char in ("w", "v") :    
-                            ispcl3 = 1  # certainely a PCL3 document
-                            pos += size - 1
-                        elif char in ("y", "m") :    
-                            ispcl3 = 1  # certainely a PCL3 document
-                            pos -= 1    # fix position : we were ahead
-                    elif ampl :        
-                        # special handling of PCL3 in which 
-                        # &l introduces combined ESCape sequences
-                        size = 0
-                        while 1 :
-                            char = minfile[pos] ; pos += 1
-                            if not char.isdigit() :
-                                break
-                            size = (size * 10) + int(char)    
-                        if char in ("a", "o", "h", "m") :    
-                            ispcl3 = 1  # certainely a PCL3 document
-                            pos -= 1    # fix position : we were ahead
-                            if char == "h" :
-                                self.setPageDict(pages, pagecount, "mediasource", self.mediasources.get(size, str(size)))
-                                mediasourcecount += 1
-                            elif char == "a" :
-                                self.setPageDict(pages, pagecount, "mediasize", self.mediasizes.get(size, str(size)))
-                                mediasizecount += 1
-                            elif char == "o" :
-                                self.setPageDict(pages, pagecount, "orientation", self.orientations.get(size, str(size)))
-                                orientationcount += 1
-                            elif char == "m" :
-                                self.setPageDict(pages, pagecount, "mediatype", self.mediatypes.get(size, str(size)))
-                                mediatypecount += 1
         except IndexError : # EOF ?
             minfile.close() # reached EOF
@@ -314,6 +330,10 @@
             sys.stderr.write("mediatypecount : %s\n" % mediatypecount)
             sys.stderr.write("escstart : %s\n" % escstart)
+            sys.stderr.write("hasirmarker : %s\n" % hasirmarker)
         
-        if (orientationcount == (pagecount - 1)) and (resets == 1) :
+        if hasirmarker :
+            self.logdebug("Rule #20 (probably a Canon ImageRunner)")
+            pagecount += 1
+        elif (orientationcount == (pagecount - 1)) and (resets == 1) :
             if resets == ejects == startgfx == mediasourcecount == escstart == 1 :
                 self.logdebug("Rule #19")
Index: /pkpgcounter/trunk/pkpgpdls/version.py
===================================================================
--- /pkpgcounter/trunk/pkpgpdls/version.py (revision 303)
+++ /pkpgcounter/trunk/pkpgpdls/version.py (revision 305)
@@ -20,5 +20,5 @@
 #
 
-__version__ = "1.74"
+__version__ = "1.75"
 
 __doc__ = """pkpgcounter : a generic Page Description Languages parser."""
Index: /pkpgcounter/trunk/NEWS
===================================================================
--- /pkpgcounter/trunk/NEWS (revision 303)
+++ /pkpgcounter/trunk/NEWS (revision 305)
@@ -22,4 +22,9 @@
 pkpgcounter News :
 
+  * 1.75 :
+  
+    - Added preliminary support for Canon ImageRunner's "LIPS" or "UFR"
+      (I don't know which) Page Description Language. 
+      
   * 1.74 :
   
