352 | | self.logdebug("Pagecount : \t\t%i" % self.pagecount) |
353 | | self.logdebug("Resets : \t\t%i" % self.resets) |
354 | | self.logdebug("Copies : \t\t%s" % self.copies) |
355 | | self.logdebug("MediaTypes : \t\t%s" % self.mediatypesvalues) |
356 | | self.logdebug("MediaSizes : \t\t%s" % self.mediasizesvalues) |
357 | | self.logdebug("MediaSources : \t\t%s" % self.mediasourcesvalues) |
358 | | self.logdebug("Orientations : \t\t%s" % self.orientationsvalues) |
359 | | self.logdebug("StartGfx : \t\t%s" % len(self.startgfx)) |
360 | | self.logdebug("EndGfx : \t\t%s" % len(self.endgfx)) |
361 | | |
362 | | return self.pagecount |
363 | | |
364 | | |
365 | | |
366 | | """ |
367 | | tagsends = { "&n" : "W", |
368 | | "&b" : "W", |
369 | | "*i" : "W", |
370 | | "*l" : "W", |
371 | | "*m" : "W", |
372 | | "*v" : "W", |
373 | | "*c" : "W", |
374 | | "(f" : "W", |
375 | | "(s" : "W", |
376 | | ")s" : "W", |
377 | | "&p" : "X", |
378 | | # "&l" : "XHAOM", # treated specially |
379 | | "&a" : "G", # TODO : 0 means next side, 1 front side, 2 back side |
380 | | "*g" : "W", |
381 | | "*r" : "sbABC", |
382 | | "*t" : "R", |
383 | | # "*b" : "VW", # treated specially because it occurs very often |
384 | | } |
385 | | irmarker = chr(0xcd) + chr(0xca) # Marker for Canon ImageRunner printers |
386 | | irmarker2 = chr(0x10) + chr(0x02) |
387 | | wasirmarker = 0 |
388 | | hasirmarker = (minfile[:2] == (irmarker)) |
389 | | pagecount = resets = ejects = backsides = startgfx = endgfx = 0 |
390 | | starb = ampl = ispcl3 = escstart = 0 |
391 | | mediasourcecount = mediasizecount = orientationcount = mediatypecount = 0 |
392 | | tag = None |
393 | | endmark = chr(0x1b) + chr(0x0c) + chr(0x00) |
394 | | asciilimit = chr(0x80) |
395 | | pages = {} |
396 | | pos = 0 |
397 | | try : |
398 | | try : |
399 | | while 1 : |
400 | | if hasirmarker and (minfile[pos:pos+2] == irmarker) : |
401 | | codop = minfile[pos+2:pos+4] |
402 | | # self.logdebug("Marker at 0x%08x (%s)" % (pos, wasirmarker)) |
403 | | length = unpack(">H", minfile[pos+8:pos+10])[0] |
404 | | pos += 20 |
405 | | if codop != irmarker2 : |
406 | | pos += length |
407 | | wasirmarker = 1 |
408 | | else : |
409 | | wasirmarker = 0 |
410 | | elif char == "\033" : |
411 | | starb = ampl = 0 |
412 | | if minfile[pos : pos+8] == r"%-12345X" : |
413 | | endpos = pos + 9 |
414 | | quotes = 0 |
415 | | while (minfile[endpos] not in endmark) and \ |
416 | | ((minfile[endpos] < asciilimit) or (quotes % 2)) : |
417 | | if minfile[endpos] == '"' : |
418 | | quotes += 1 |
419 | | endpos += 1 |
420 | | self.setPageDict(pages, pagecount, "escaped", minfile[pos : endpos]) |
421 | | pos += (endpos - pos) |
422 | | else : |
423 | | # |
424 | | # <ESC>*b###y#m###v###w... -> PCL3 raster graphics |
425 | | # <ESC>*b###W -> Start of a raster data row/block |
426 | | # <ESC>*b###V -> Start of a raster data plane |
427 | | # <ESC>*c###W -> Start of a user defined pattern |
428 | | # <ESC>*i###W -> Start of a viewing illuminant block |
429 | | # <ESC>*l###W -> Start of a color lookup table |
430 | | # <ESC>*m###W -> Start of a download dither matrix block |
431 | | # <ESC>*v###W -> Start of a configure image data block |
432 | | # <ESC>*r1A -> Start Gfx |
433 | | # <ESC>(s###W -> Start of a characters description block |
434 | | # <ESC>)s###W -> Start of a fonts description block |
435 | | # <ESC>(f###W -> Start of a symbol set block |
436 | | # <ESC>&b###W -> Start of configuration data block |
437 | | # <ESC>&l###X -> Number of copies for current page |
438 | | # <ESC>&n###W -> Starts an alphanumeric string ID block |
439 | | # <ESC>&p###X -> Start of a non printable characters block |
440 | | # <ESC>&a2G -> Back side when duplex mode as generated by rastertohp |
441 | | # <ESC>*g###W -> Needed for planes in PCL3 output |
442 | | # <ESC>&l###H (or only 0 ?) -> Eject if NumPlanes > 1, as generated by rastertohp. Also defines mediasource |
443 | | # <ESC>&l###A -> mediasize |
444 | | # <ESC>&l###O -> orientation |
445 | | # <ESC>&l###M -> mediatype |
446 | | # <ESC>*t###R -> gfx resolution |
447 | | # |
448 | | tagstart = minfile[pos] ; pos += 1 |
449 | | if tagstart in "E9=YZ" : # one byte PCL tag |
450 | | if tagstart == "E" : |
451 | | resets += 1 |
452 | | continue # skip to next tag |
453 | | tag = tagstart + minfile[pos] ; pos += 1 |
454 | | if tag == "*b" : |
455 | | starb = 1 |
456 | | tagend = "VW" |
457 | | elif tag == "&l" : |
458 | | ampl = 1 |
459 | | tagend = "XHAOM" |
460 | | else : |
461 | | try : |
462 | | tagend = tagsends[tag] |
463 | | except KeyError : |
464 | | continue # Unsupported PCL tag |
465 | | # Now read the numeric argument |
466 | | size = 0 |
467 | | while 1 : |
468 | | char = minfile[pos] ; pos += 1 |
469 | | if not char.isdigit() : |
470 | | break |
471 | | size = (size * 10) + int(char) |
472 | | if char in tagend : |
473 | | if tag == "&l" : |
474 | | if char == "X" : |
475 | | self.setPageDict(pages, pagecount, "copies", size) |
476 | | elif char == "H" : |
477 | | self.setPageDict(pages, pagecount, "mediasource", self.mediasources.get(size, str(size))) |
478 | | mediasourcecount += 1 |
479 | | ejects += 1 |
480 | | elif char == "A" : |
481 | | self.setPageDict(pages, pagecount, "mediasize", self.mediasizes.get(size, str(size))) |
482 | | mediasizecount += 1 |
483 | | elif char == "O" : |
484 | | self.setPageDict(pages, pagecount, "orientation", self.orientations.get(size, str(size))) |
485 | | orientationcount += 1 |
486 | | elif char == "M" : |
487 | | self.setPageDict(pages, pagecount, "mediatype", self.mediatypes.get(size, str(size))) |
488 | | mediatypecount += 1 |
489 | | elif tag == "*r" : |
490 | | # Special tests for PCL3 |
491 | | if (char == "s") and size : |
492 | | while 1 : |
493 | | char = minfile[pos] ; pos += 1 |
494 | | if char == "A" : |
495 | | break |
496 | | elif (char == "b") and (minfile[pos] == "C") and not size : |
497 | | ispcl3 = 1 # Certainely a PCL3 file |
498 | | startgfx += (char == "A") and (minfile[pos - 2] in ("0", "1", "2", "3")) # Start Gfx |
499 | | endgfx += (not size) and (char in ("C", "B")) # End Gfx |
500 | | elif tag == "*t" : |
501 | | escstart += 1 |
502 | | elif (tag == "&a") and (size == 2) : |
503 | | # We are on the backside, so mark current page as duplex |
504 | | self.setPageDict(pages, pagecount, "duplex", 1) |
505 | | backsides += 1 # Back side in duplex mode |
506 | | else : |
507 | | # we just ignore the block. |
508 | | if tag == "&n" : |
509 | | # we have to take care of the operation id byte |
510 | | # which is before the string itself |
511 | | size += 1 |
512 | | pos += size |
513 | | else : |
514 | | if starb : |
515 | | # special handling of PCL3 in which |
516 | | # *b introduces combined ESCape sequences |
517 | | size = 0 |
518 | | while 1 : |
519 | | char = minfile[pos] ; pos += 1 |
520 | | if not char.isdigit() : |
521 | | break |
522 | | size = (size * 10) + int(char) |
523 | | if char in ("w", "v") : |
524 | | ispcl3 = 1 # certainely a PCL3 document |
525 | | pos += size - 1 |
526 | | elif char in ("y", "m") : |
527 | | ispcl3 = 1 # certainely a PCL3 document |
528 | | pos -= 1 # fix position : we were ahead |
529 | | elif ampl : |
530 | | # special handling of PCL3 in which |
531 | | # &l introduces combined ESCape sequences |
532 | | size = 0 |
533 | | while 1 : |
534 | | char = minfile[pos] ; pos += 1 |
535 | | if not char.isdigit() : |
536 | | break |
537 | | size = (size * 10) + int(char) |
538 | | if char in ("a", "o", "h", "m") : |
539 | | ispcl3 = 1 # certainely a PCL3 document |
540 | | pos -= 1 # fix position : we were ahead |
541 | | if char == "h" : |
542 | | self.setPageDict(pages, pagecount, "mediasource", self.mediasources.get(size, str(size))) |
543 | | mediasourcecount += 1 |
544 | | elif char == "a" : |
545 | | self.setPageDict(pages, pagecount, "mediasize", self.mediasizes.get(size, str(size))) |
546 | | mediasizecount += 1 |
547 | | elif char == "o" : |
548 | | self.setPageDict(pages, pagecount, "orientation", self.orientations.get(size, str(size))) |
549 | | orientationcount += 1 |
550 | | elif char == "m" : |
551 | | self.setPageDict(pages, pagecount, "mediatype", self.mediatypes.get(size, str(size))) |
552 | | mediatypecount += 1 |
553 | | except IndexError : # EOF ? |
554 | | pass |
555 | | finally : |
556 | | minfile.close() |
557 | | |
558 | | # if pagecount is still 0, we will use the number |
559 | | # of resets instead of the number of form feed characters. |
560 | | # but the number of resets is always at least 2 with a valid |
561 | | # pcl file : one at the very start and one at the very end |
562 | | # of the job's data. So we substract 2 from the number of |
563 | | # resets. And since on our test data we needed to substract |
564 | | # 1 more, we finally substract 3, and will test several |
565 | | # PCL files with this. If resets < 2, then the file is |
566 | | # probably not a valid PCL file, so we use 0 |
567 | | |
568 | | if self.debug : |
569 | | sys.stderr.write("pagecount : %s\n" % pagecount) |
570 | | sys.stderr.write("resets : %s\n" % resets) |
571 | | sys.stderr.write("ejects : %s\n" % ejects) |
572 | | sys.stderr.write("backsides : %s\n" % backsides) |
573 | | sys.stderr.write("startgfx : %s\n" % startgfx) |
574 | | sys.stderr.write("endgfx : %s\n" % endgfx) |
575 | | sys.stderr.write("mediasourcecount : %s\n" % mediasourcecount) |
576 | | sys.stderr.write("mediasizecount : %s\n" % mediasizecount) |
577 | | sys.stderr.write("orientationcount : %s\n" % orientationcount) |
578 | | sys.stderr.write("mediatypecount : %s\n" % mediatypecount) |
579 | | sys.stderr.write("escstart : %s\n" % escstart) |
580 | | sys.stderr.write("hasirmarker : %s\n" % hasirmarker) |
581 | | |
582 | | if hasirmarker : |
583 | | self.logdebug("Rule #20 (probably a Canon ImageRunner)") |
584 | | pagecount += 1 |
585 | | elif (orientationcount == (pagecount - 1)) and (resets == 1) : |
586 | | if resets == ejects == startgfx == mediasourcecount == escstart == 1 : |
587 | | self.logdebug("Rule #19") |
588 | | else : |
589 | | self.logdebug("Rule #1") |
590 | | pagecount -= 1 |
591 | | elif pagecount and (pagecount == orientationcount) : |
592 | | self.logdebug("Rule #2") |
593 | | elif resets == ejects == mediasourcecount == mediasizecount == escstart == 1 : |
594 | | #if ((startgfx and endgfx) and (startgfx != endgfx)) or (startgfx == endgfx == 0) : |
595 | | if (startgfx and endgfx) or (startgfx == endgfx == 0) : |
596 | | self.logdebug("Rule #3") |
597 | | pagecount = orientationcount |
598 | | elif (endgfx and not startgfx) and (pagecount > orientationcount) : |
599 | | self.logdebug("Rule #4") |
600 | | pagecount = orientationcount |
601 | | else : |
602 | | self.logdebug("Rule #5") |
603 | | pagecount += 1 |
604 | | elif (ejects == mediasourcecount == orientationcount) and (startgfx == endgfx) : |
605 | | if (resets == 2) and (orientationcount == (pagecount - 1)) and (orientationcount > 1) : |
606 | | self.logdebug("Rule #6") |
607 | | pagecount = orientationcount |
608 | | elif pagecount == mediasourcecount == escstart : |
609 | | self.logdebug("Rule #7") |
610 | | elif resets == startgfx == endgfx == mediasizecount == orientationcount == escstart == 1 : |
611 | | self.logdebug("Rule #8") |
612 | | elif resets == startgfx == endgfx == (pagecount - 1) : |
613 | | self.logdebug("Rule #9") |
614 | | elif (not startgfx) and (not endgfx) : |
615 | | self.logdebug("Rule #10") |
616 | | elif (resets == 2) and (startgfx == endgfx) and (mediasourcecount == 1) : |
617 | | if orientationcount == (pagecount - 1) : |
618 | | self.logdebug("Rule #11") |
619 | | pagecount = orientationcount |
620 | | elif not pagecount : |
621 | | self.logdebug("Rule #17") |
622 | | pagecount = ejects |
623 | | elif (resets == 1) and (startgfx == endgfx) and (mediasourcecount == 0) : |
624 | | if (startgfx > 1) and (startgfx != (pagecount - 1)) : |
625 | | self.logdebug("Rule #12") |
626 | | pagecount -= 1 |
627 | | else : |
628 | | self.logdebug("Rule #18") |
629 | | elif startgfx == endgfx : |
630 | | self.logdebug("Rule #13") |
631 | | pagecount = startgfx |
632 | | elif startgfx == (endgfx - 1) : |
633 | | self.logdebug("Rule #14") |
634 | | pagecount = startgfx |
635 | | elif (startgfx == 1) and not endgfx : |
636 | | self.logdebug("Rule #15") |
637 | | pass |
638 | | else : |
639 | | self.logdebug("Rule #16") |
640 | | pagecount = abs(startgfx - endgfx) |
641 | | |
642 | | defaultpjlcopies = 1 |
643 | | defaultduplexmode = "Simplex" |
644 | | defaultpapersize = "" |
645 | | oldpjlcopies = -1 |
646 | | oldduplexmode = "" |
647 | | oldpapersize = "" |
648 | | for pnum in range(pagecount) : |
649 | | # if no number of copies defined, take the preceding one else the one set before any page else 1. |
650 | | page = pages.get(pnum, pages.get(pnum - 1, pages.get(0, { "copies" : 1, "mediasource" : "Main", "mediasize" : "Default", "mediatype" : "Plain", "orientation" : "Portrait", "escaped" : "", "duplex": 0}))) |
651 | | pjlstuff = page["escaped"] |
652 | | if pjlstuff : |
653 | | pjlparser = pjl.PJLParser(pjlstuff) |
654 | | nbdefaultcopies = int(pjlparser.default_variables.get("COPIES", -1)) |
655 | | nbcopies = int(pjlparser.environment_variables.get("COPIES", -1)) |
656 | | nbdefaultqty = int(pjlparser.default_variables.get("QTY", -1)) |
657 | | nbqty = int(pjlparser.environment_variables.get("QTY", -1)) |
658 | | if nbdefaultcopies > -1 : |
659 | | defaultpjlcopies = nbdefaultcopies |
660 | | if nbdefaultqty > -1 : |
661 | | defaultpjlcopies = nbdefaultqty |
662 | | if nbcopies > -1 : |
663 | | pjlcopies = nbcopies |
664 | | elif nbqty > -1 : |
665 | | pjlcopies = nbqty |
666 | | else : |
667 | | if oldpjlcopies == -1 : |
668 | | pjlcopies = defaultpjlcopies |
669 | | else : |
670 | | pjlcopies = oldpjlcopies |
671 | | if page["duplex"] : |
672 | | duplexmode = "Duplex" |
673 | | else : |
674 | | defaultdm = pjlparser.default_variables.get("DUPLEX", "") |
675 | | if defaultdm : |
676 | | if defaultdm.upper() == "ON" : |
677 | | defaultduplexmode = "Duplex" |
678 | | else : |
679 | | defaultduplexmode = "Simplex" |
680 | | envdm = pjlparser.environment_variables.get("DUPLEX", "") |
681 | | if envdm : |
682 | | if envdm.upper() == "ON" : |
683 | | duplexmode = "Duplex" |
684 | | else : |
685 | | duplexmode = "Simplex" |
686 | | else : |
687 | | duplexmode = oldduplexmode or defaultduplexmode |
688 | | defaultps = pjlparser.default_variables.get("PAPER", "") |
689 | | if defaultps : |
690 | | defaultpapersize = defaultps |
691 | | envps = pjlparser.environment_variables.get("PAPER", "") |
692 | | if envps : |
693 | | papersize = envps |
694 | | else : |
695 | | if not oldpapersize : |
696 | | papersize = defaultpapersize |
697 | | else : |
698 | | papersize = oldpapersize |
699 | | else : |
700 | | if oldpjlcopies == -1 : |
701 | | pjlcopies = defaultpjlcopies |
702 | | else : |
703 | | pjlcopies = oldpjlcopies |
704 | | |
705 | | duplexmode = (page["duplex"] and "Duplex") or oldduplexmode or defaultduplexmode |
706 | | if not oldpapersize : |
707 | | papersize = defaultpapersize |
708 | | else : |
709 | | papersize = oldpapersize |
710 | | papersize = oldpapersize or page["mediasize"] |
711 | | if page["mediasize"] != "Default" : |
712 | | papersize = page["mediasize"] |
713 | | if not duplexmode : |
714 | | duplexmode = oldduplexmode or defaultduplexmode |
715 | | oldpjlcopies = pjlcopies |
716 | | oldduplexmode = duplexmode |
717 | | oldpapersize = papersize |
718 | | copies = pjlcopies * page["copies"] |
719 | | pagecount += (copies - 1) |
720 | | self.logdebug("%s*%s*%s*%s*%s*%s*BW" % (copies, \ |
721 | | page["mediatype"], \ |
722 | | papersize, \ |
723 | | page["orientation"], \ |
724 | | page["mediasource"], \ |
725 | | duplexmode)) |
726 | | |
727 | | return pagecount |
728 | | """ |
| 399 | self.logdebug("Pagecount : \t\t\t%i" % self.pagecount) |
| 400 | self.logdebug("Resets : \t\t\t%i" % self.resets) |
| 401 | self.logdebug("Copies : \t\t\t%s" % self.copies) |
| 402 | self.logdebug("NbCopiesMarks : \t\t%i" % len(self.copies)) |
| 403 | self.logdebug("MediaTypes : \t\t\t%s" % self.mediatypesvalues) |
| 404 | self.logdebug("NbMediaTypes : \t\t\t%i" % len(self.mediatypesvalues)) |
| 405 | self.logdebug("MediaSizes : \t\t\t%s" % self.mediasizesvalues) |
| 406 | self.logdebug("NbMediaSizes : \t\t\t%i" % len(self.mediasizesvalues)) |
| 407 | self.logdebug("MediaSources : \t\t\t%s" % self.mediasourcesvalues) |
| 408 | nbmediasourcesdefault = len([m for m in self.mediasourcesvalues if m == 'Default']) |
| 409 | self.logdebug("MediaSourcesDefault : \t\t%i" % nbmediasourcesdefault) |
| 410 | self.logdebug("MediaSourcesNOTDefault : \t%i" % (len(self.mediasourcesvalues) - nbmediasourcesdefault)) |
| 411 | self.logdebug("Orientations : \t\t\t%s" % self.orientationsvalues) |
| 412 | self.logdebug("NbOrientations : \t\t\t%i" % len(self.orientationsvalues)) |
| 413 | self.logdebug("StartGfx : \t\t\t%s" % len(self.startgfx)) |
| 414 | self.logdebug("EndGfx : \t\t\t%s" % len(self.endgfx)) |
| 415 | self.logdebug("BackSides : \t\t\t%s" % self.backsides) |
| 416 | self.logdebug("NbBackSides : \t\t\t%i" % len(self.backsides)) |
| 417 | |
| 418 | return self.pagecount or nbmediasourcesdefault |