home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / lib / hplip / base / mfpdtf.py < prev    next >
Encoding:
Python Source  |  2007-04-04  |  17.4 KB  |  504 lines

  1. # -*- coding: utf-8 -*-
  2. #
  3. # (c) Copyright 2003-2007 Hewlett-Packard Development Company, L.P.
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18. #
  19. # Author: Don Welch
  20. #
  21.  
  22. # Std Lib
  23. import struct, cStringIO
  24.  
  25. # Local
  26. from g import *
  27. from codes import *
  28.  
  29. # Page flags
  30. NEW_PAGE =            0x01
  31. END_PAGE  =           0x02
  32. NEW_DOCUMENT =        0x04
  33. END_DOCUMENT =        0x08
  34. END_STREAM  =         0x10
  35. RESERVED_20 =         0x20
  36. RESERVED_40 =         0x40
  37. RESERVED_80 =         0x80
  38.  
  39. MFPDTF_RASTER_BITMAP  = 0
  40. MFPDTF_RASTER_GRAYMAP = 1
  41. MFPDTF_RASTER_MH      = 2
  42. MFPDTF_RASTER_MR      = 3
  43. MFPDTF_RASTER_MMR     = 4
  44. MFPDTF_RASTER_RGB     = 5
  45. MFPDTF_RASTER_YCC411  = 6
  46. MFPDTF_RASTER_JPEG    = 7
  47. MFPDTF_RASTER_PCL     = 8
  48. MFPDTF_RASTER_NOT     = 9
  49.  
  50. # Data types for FH
  51. DT_UNKNOWN       = 0
  52. DT_FAX_IMAGES    = 1
  53. DT_SCANNED_IMAGES= 2
  54. DT_DIAL_STRINGS  = 3
  55. DT_DEMO_PAGES    = 4
  56. DT_SPEED_DIALS   = 5
  57. DT_FAX_LOGS      = 6
  58. DT_CFG_PARMS     = 7
  59. DT_LANG_STRS     = 8
  60. DT_JUNK_FAX_CSIDS= 9  
  61. DT_REPORT_STRS   = 10  
  62. DT_FONTS         = 11
  63. DT_TTI_BITMAP    = 12
  64. DT_COUNTERS      = 13
  65. DT_DEF_PARMS     = 14  
  66. DT_SCAN_OPTIONS  = 15
  67. DT_FW_JOB_TABLE  = 17
  68.  
  69. # Raster data record types
  70. RT_START_PAGE = 0
  71. RT_RASTER = 1
  72. RT_END_PAGE = 2
  73.  
  74. # FH
  75. FIXED_HEADER_SIZE = 8
  76.  
  77. # Variants
  78. IMAGE_VARIANT_HEADER_SIZE = 10
  79. DIAL_STRINGS_VARIANT_HEADER_SIZE = 6
  80. FAX_IMAGE_VARIANT_HEADER_SIZE = 74
  81.  
  82. # Data records
  83. SOP_RECORD_SIZE = 36
  84. RASTER_RECORD_SIZE = 4
  85. EOP_RECORD_SIZE = 12
  86. DIAL_STRING_RECORD_SIZE = 51
  87.  
  88. # Page flags 
  89. PAGE_FLAG_NEW_PAGE = 0x01
  90. PAGE_FLAG_END_PAGE = 0x02
  91. PAGE_FLAG_NEW_DOC = 0x04
  92. PAGE_FLAG_END_DOC = 0x08
  93. PAGE_FLAG_END_STREAM = 0x10
  94.  
  95. # Fax data variant header data source
  96. SRC_UNKNOWN = 0
  97. SRC_HOST = 2
  98. SRC_SCANNER = 5
  99. SRC_HOST_THEN_SCANNER = 6
  100. SRC_SCANNER_THEN_HOST = 7
  101.  
  102. # Fax data variant header TTI header control
  103. TTI_NONE = 0
  104. TTI_PREPENDED_TO_IMAGE = 1
  105. TTI_OVERLAYED_ON_IMAGE = 2
  106.  
  107. MAJOR_VER = 2
  108. MINOR_VER = 0
  109.  
  110.  
  111. def parseFixedHeader(buffer):
  112.     fmt = "<IHBB"
  113.     block_len, header_len, data_type, page_flags = struct.unpack(fmt, buffer[:8])
  114.     page_flags = page_flags & 0x1f
  115.     return block_len, header_len, data_type, page_flags
  116.  
  117. def parseImageVariantHeader(buffer, data_type):
  118.     if data_type == DT_SCANNED_IMAGES:
  119.         fmt = "<BBHHHH"
  120.         major_ver, minor_ver, src_pages, copies_per_page, zoom, jpeg_q_factor = struct.unpack(fmt, buffer[:10])
  121.         return major_ver, minor_ver, src_pages, copies_per_page, zoom, jpeg_q_factor
  122.     elif data_type == DT_FAX_IMAGES:
  123.         pass
  124.  
  125. def parseRecord(buffer):
  126.     record_type = struct.unpack("<B", buffer[0])[0]
  127.  
  128.     if record_type == RT_START_PAGE:
  129.         fmt = "<BBHHHIIIHHIII"
  130.         id, encoding, page_num, black_ppr, black_bpp, black_rpp, black_hort_dpi, black_vert_dpi, cmy_ppr, cmy_bpp, cmy_rpp, cmy_hort_dpi, cmy_vert_dpi = \
  131.             struct.unpack(fmt, buffer[:SOP_RECORD_SIZE])
  132.         assert id == record_type
  133.         return id, (encoding, page_num, black_ppr, black_bpp, black_rpp, black_hort_dpi, black_vert_dpi, cmy_ppr, cmy_bpp, cmy_rpp, cmy_hort_dpi, cmy_vert_dpi)
  134.  
  135.     elif record_type == RT_RASTER:
  136.         fmt = "<BBH"
  137.         id, unused, data_size = struct.unpack(fmt, buffer[:RASTER_RECORD_SIZE])
  138.         assert id == record_type
  139.         return id, (unused, data_size)
  140.  
  141.     elif record_type == RT_END_PAGE:
  142.         fmt = "<BBBBII"
  143.         id, unused1, unused2, unused3, black_rows, cmy_rows = struct.unpack(fmt, buffer[:EOP_RECORD_SIZE])
  144.         assert id == record_type
  145.         return id, (unused1, unused2, unused3, black_rows, cmy_rows)
  146.  
  147.     log.error("Error: Invalid record type: %d" % record_type)
  148.     raise Error(ERROR_INTERNAL)
  149.  
  150.  
  151.  
  152. def readChannelToStream(device, channel_id, stream, single_read=True, callback=None):
  153.     STATE_END, STATE_FIXED_HEADER, STATE_VARIANT_HEADER, STATE_RECORD = range(4)
  154.     state, total_bytes, block_remaining, header_remaining, data_remaining = 1, 0, 0, 0, 0
  155.     endScan = False
  156.     while state != STATE_END:
  157.         log.debug("**** State %d ****" % state)
  158.         if state == STATE_FIXED_HEADER: 
  159.  
  160.             if endScan:
  161.                 state = STATE_END
  162.                 break
  163.  
  164.             if data_remaining == 0:
  165.                 fields, data = device.readChannel(channel_id)
  166.                 data_remaining = len(data)
  167.                 if callback is not None:
  168.                     endScan = callback()
  169.  
  170.             block_len, header_len, data_type, page_flags = parseFixedHeader(data)
  171.             block_remaining, header_remaining = block_len-FIXED_HEADER_SIZE, header_len-FIXED_HEADER_SIZE
  172.             log.debug("Fixed header: (datalen=%d(0x%x),blocklen=%d(0x%x),headerlen=%d(0x%x),datatype=0x%x,pageflags=0x%x)" % 
  173.                 (len(data), len(data), block_len, block_len, header_len, header_len, data_type, page_flags))
  174.             data_remaining -= FIXED_HEADER_SIZE
  175.             data = data[FIXED_HEADER_SIZE:]
  176.             state = STATE_RECORD
  177.             log.debug("Data: data=%d,block=%d,header=%d" % (data_remaining, block_remaining, header_remaining))
  178.  
  179.             if page_flags & PAGE_FLAG_END_STREAM:
  180.                 state = STATE_END
  181.                 break
  182.  
  183.             if header_remaining > 0:
  184.                 state = STATE_VARIANT_HEADER
  185.  
  186.  
  187.         elif state == STATE_VARIANT_HEADER:
  188.             if data_type == DT_SCANNED_IMAGES:
  189.                 major_ver, minor_ver, src_pages, copies_per_page, zoom, jpeg_q_factor = parseImageVariantHeader(data, data_type)
  190.                 log.debug("Variant header: (major/minor=%d/%d,src_pages=%d,copies_per_page=%d,zoom=%d,jpeg_q_factor=%d" % 
  191.                     (major_ver, minor_ver, src_pages, copies_per_page, zoom, jpeg_q_factor))
  192.                 data = data[IMAGE_VARIANT_HEADER_SIZE:]
  193.                 block_remaining -= IMAGE_VARIANT_HEADER_SIZE
  194.                 header_remaining -= IMAGE_VARIANT_HEADER_SIZE
  195.                 data_remaining -= IMAGE_VARIANT_HEADER_SIZE
  196.  
  197.             elif data_type == DT_FAX_IMAGES:
  198.                 log.error("Unsupported data type")
  199.  
  200.             else:
  201.                 log.error("Unsupported data type")
  202.  
  203.             log.debug("Data: data=%d,block=%d,header=%d" % (data_remaining, block_remaining, header_remaining))
  204.  
  205.             if header_remaining > 0:
  206.                 log.error("Header size error.")
  207.                 state = STATE_END
  208.                 continue
  209.  
  210.             state = STATE_RECORD
  211.             if block_remaining == 0:
  212.                 state = STATE_FIXED_HEADER
  213.             continue
  214.  
  215.         elif state == STATE_RECORD:
  216.             record_type, record = parseRecord(data)
  217.  
  218.             if record_type == RT_START_PAGE:
  219.                 encoding, page_num, black_ppr, black_bpp, black_rpp, black_hort_dpi, black_vert_dpi, \
  220.                     cmy_ppr, cmy_bpp, cmy_rpp, cmy_hort_dpi, cmy_vert_dpi = record
  221.                 log.debug("Start page record: (encoding=0x%x, page=%d)" % (encoding, page_num))
  222.                 data = data[SOP_RECORD_SIZE:]
  223.                 block_remaining -= SOP_RECORD_SIZE
  224.                 data_remaining -= SOP_RECORD_SIZE
  225.                 if block_remaining != 0:
  226.                     log.error("Block size error.")
  227.                     state = STATE_END
  228.                     continue
  229.  
  230.                 if single_read:
  231.                     state = STATE_END
  232.                 else:                    
  233.                     state = STATE_FIXED_HEADER
  234.                     log.debug("Data: data=%d,block=%d,header=%d" % (data_remaining, block_remaining, header_remaining))
  235.                 continue
  236.  
  237.             elif record_type == RT_RASTER:
  238.                 unused, data_size = record
  239.                 log.debug("Raster record: (data size=%d(0x%x))" % (data_size, data_size))
  240.                 data = data[RASTER_RECORD_SIZE:]
  241.                 block_remaining -= RASTER_RECORD_SIZE
  242.                 data_remaining -= RASTER_RECORD_SIZE
  243.                 log.debug("Data: data=%d,block=%d,header=%d" % (data_remaining, block_remaining, header_remaining))
  244.  
  245.                 if block_remaining > 0 and data_remaining > 0:
  246.                     log.debug("Writing remainder of data...")
  247.                     data_len = len(data)
  248.                     log.debug("Data len=%d(0x%x)" % (data_len,data_len))
  249.                     stream.write(data[:block_remaining])
  250.                     block_remaining -= data_len
  251.                     data_remaining -= data_len
  252.  
  253.                     if data_remaining != 0:
  254.                         log.error("Data size error")
  255.                         state = STATE_END
  256.                         continue
  257.  
  258.                 while block_remaining > 0:
  259.                     if endScan:
  260.                         #state = STATE_END
  261.                         break
  262.  
  263.                     log.debug("Reading more data from device...")
  264.                     fields, data = device.readChannel(channel_id)
  265.  
  266.                     if callback is not None:
  267.                         endScan = callback()
  268.  
  269.                     data_len = len(data)
  270.                     log.debug("Data len=%d(0x%x)" % (data_len,data_len))
  271.                     stream.write(data[:block_remaining])
  272.                     total_bytes += data_len
  273.                     block_remaining -= data_len
  274.  
  275.                 if block_remaining != 0:
  276.                     log.error("Block size error.")
  277.                     state = STATE_END
  278.                     continue
  279.  
  280.                 state = STATE_FIXED_HEADER
  281.                 continue
  282.  
  283.             elif record_type == RT_END_PAGE:
  284.                 unused1, unused2, unused3, black_rows, cmy_rows = record
  285.                 log.debug("End page record: (black_rows=%d,cmy_rows=%d)" % (black_rows, cmy_rows))
  286.                 data = data[EOP_RECORD_SIZE:]
  287.                 block_remaining -= EOP_RECORD_SIZE
  288.                 data_remaining -= EOP_RECORD_SIZE
  289.                 if block_remaining != 0:
  290.                     log.error("Block size error.")
  291.                 log.debug("Data: data=%d,block=%d,header=%d" % (data_remaining, block_remaining, header_remaining))
  292.  
  293.                 if page_flags & PAGE_FLAG_END_DOC or \
  294.                    page_flags & PAGE_FLAG_END_STREAM:
  295.                     state = STATE_END
  296.                 else:
  297.                     state = STATE_FIXED_HEADER
  298.                 continue
  299.  
  300.     log.debug("Read %d bytes" % total_bytes)
  301.     return endScan 
  302.  
  303.  
  304.  
  305. def buildMFPDTFBlock(data_type, page_flags=0, send_variant=False, data=None):
  306.     # Fixed header
  307.     # [Variant header - dial, fax, or scan]
  308.     # Data Record
  309.  
  310.     block = cStringIO.StringIO()
  311.     block.write(struct.pack("<I", 0)) # Block len (4bytes)
  312.     header_len = FIXED_HEADER_SIZE
  313.  
  314.     if send_variant:
  315.         if data_type == DT_DIAL_STRINGS:
  316.             header_len += DIAL_STRINGS_VARIANT_HEADER_SIZE
  317.  
  318.         elif data_type == DT_FAX_IMAGES:
  319.             header_len += FAX_IMAGE_VARIANT_HEADER_SIZE
  320.  
  321.     block.write(struct.pack("<H", header_len)) # Header len (2 bytes)
  322.     block.write(struct.pack("<B", data_type)) # Data type (1 byte)
  323.     block.write(struct.pack("<B", page_flags)) # Page flags (1 byte)
  324.  
  325.     if send_variant:
  326.         if data_type == DT_DIAL_STRINGS:
  327.             block.write(struct.pack("<BB", MAJOR_VER, MINOR_VER))
  328.             block.write(struct.pack("<H", 1)) # num strings
  329.             block.write(struct.pack("<H", 51)) # ?
  330.  
  331.         elif data_type == DT_FAX_IMAGES:
  332.             block.write(struct.pack("<BB", MAJOR_VER, MINOR_VER))
  333.             block.write(struct.pack("<B", SRC_HOST)) # Data source (1 byte)
  334.             block.write(struct.pack("<H", 1)) # Num pages (2 bytes)
  335.             block.write(struct.pack("<B", TTI_NONE)) # TTI control
  336.             block.write(struct.pack("<I", 0)) # time (4 bytes)
  337.             block.write("\x00"*20) # T30_CSI (20 bytes)
  338.             block.write("\x20"*20) # T30_SUB (20 bytes)
  339.             block.write("\x20"*20) # T30_PWD (20 bytes)
  340.             block.write("<I", 0) # xaction ID (4 bytes)
  341.  
  342.     if data_type == DT_DIAL_STRINGS:
  343.         if data is not None:
  344.             dial_string = data['dial-string']
  345.             block.write(dial_string)
  346.             block.write('\x00'*(51-len(dial_string)))
  347.  
  348.     elif data_type == DT_FAX_IMAGES:
  349.         pass
  350.  
  351.  
  352.     # fixed header (8 bytes):
  353.     # 
  354.     # +----------------------------+
  355.     # |                            |
  356.     # | block len (32 bits)        |
  357.     # | length of entire           |
  358.     # | block of data              |
  359.     # +----------------------------+
  360.     # |                            |
  361.     # | header length (16 bits)    |
  362.     # | length of fixed and        |
  363.     # | variant header (if any)    |
  364.     # | ==8 if no variant (fixed   |
  365.     # |   only                     |
  366.     # | >8 if variant header       |
  367.     # |                            |
  368.     # +----------------------------+
  369.     # |                            | 1=FAX
  370.     # | data type (8 bits)         | 3=DIAL_STRINGS
  371.     # | data type of data record(s)| 12=TTI BITMAP
  372.     # |                            |
  373.     # +----------------------------+
  374.     # |                            |
  375.     # | page flags (8 bits)        |
  376.     # |                            |
  377.     # +----------------------------+
  378.     #
  379.     # followed by variant header and/or 
  380.     # data record(s)...
  381.     #
  382.     # image header variant (10 bytes)
  383.     # 
  384.     # +----------------------------+
  385.     # |                            |
  386.     # | major ver (8 bits)         |
  387.     # |                            |
  388.     # +----------------------------+
  389.     # |                            |
  390.     # | minor ver (8 bits)         |
  391.     # |                            |
  392.     # +----------------------------+
  393.     # |                            |
  394.     # | source pages (16 bits)     |
  395.     # |                            |
  396.     # +----------------------------+
  397.     # |                            |
  398.     # | copies/page (16 bits)      |
  399.     # |                            |
  400.     # +----------------------------+
  401.     # |                            |
  402.     # | zoom factor (16 bits)      |
  403.     # |                            |
  404.     # +----------------------------+
  405.     # |                            |
  406.     # | jpeg Q factor (16 bits)    |
  407.     # |                            |
  408.     # +----------------------------+
  409.     #
  410.     # dial strings variant header (6 bytes)
  411.     #
  412.     # +----------------------------+
  413.     # |                            |
  414.     # | major ver (8 bits)         |
  415.     # |                            |
  416.     # +----------------------------+
  417.     # |                            |
  418.     # | minor ver (8 bits)         |
  419.     # |                            |
  420.     # +----------------------------+
  421.     # |                            |
  422.     # | num strings (16 bits)      |
  423.     # |                            |
  424.     # +----------------------------+
  425.     # |                            |
  426.     # | dial string len (16 bits)  |
  427.     # |                            |
  428.     # +----------------------------+
  429.     #
  430.     # dial string data part
  431.     # +----------------------------+
  432.     # |                            |
  433.     # | dial string (51 bytes)     |
  434.     # |                            |
  435.     # +----------------------------+
  436.     #
  437.     # start page (SOP) record (36 bytes)
  438.     # 
  439.     # +----------------------------+
  440.     # |                            |
  441.     # | id = 0 (8 bits)            |
  442.     # |                            |
  443.     # +----------------------------+
  444.     # |                            |
  445.     # | encoding (8 bits)          |
  446.     # |                            |
  447.     # +----------------------------+
  448.     # |                            |
  449.     # | page num (16 bits)         |
  450.     # |                            |
  451.     # +----------------------------+
  452.     # |                            |
  453.     # | black data desc (16 bytes) |
  454.     # |                            |
  455.     # +----------------------------+
  456.     # |                            |
  457.     # | cmy data desc (16 bytes)   |
  458.     # |                            |
  459.     # +----------------------------+
  460.     #
  461.     #
  462.     # raster data record (4 bytes + data)
  463.     # 
  464.     # +----------------------------+
  465.     # |                            |
  466.     # | id = 1 (8 bits)            |
  467.     # |                            |
  468.     # +----------------------------+
  469.     # |                            |
  470.     # | unused (8 bits)            |
  471.     # |                            |
  472.     # +----------------------------+
  473.     # |                            |
  474.     # | data bytes (n) (16 bits)   |
  475.     # |                            |
  476.     # +----------------------------+
  477.     # |                            |
  478.     # | data (n bytes)             |
  479.     # |                            |
  480.     # +----------------------------+
  481.     #
  482.     #
  483.     # end page (EOP) record (12 bytes)
  484.     # 
  485.     # +----------------------------+
  486.     # |                            |
  487.     # | id = 2 (8 bits)            |
  488.     # |                            |
  489.     # +----------------------------+
  490.     # |                            |
  491.     # | unused (24 bits)           |
  492.     # |                            |
  493.     # +----------------------------+
  494.     # |                            |
  495.     # | rows of black (32 bits)    |
  496.     # |                            |
  497.     # +----------------------------+
  498.     # |                            |
  499.     # | rows of cmy (32 bits)      |
  500.     # |                            |
  501.     # +----------------------------+
  502.     #    
  503.  
  504.