~mimose/+junk/hplip-3.16.11

« back to all changes in this revision

Viewing changes to base/mfpdtf.py

  • Committer: guoyalong
  • Date: 2017-09-20 10:13:05 UTC
  • Revision ID: guoyalong@kylinos.cn-20170920101305-82zaolzpv1qghz29
Modified debian/control & debian/rules.

Show diffs side-by-side

added added

removed removed

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