/usr/lib/cups/filter/rastertosag-gdi is in printer-driver-sag-gdi 0.1-3.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | #!/usr/bin/python -u
#coding=utf8
# CUPS raster filter for Ricoh Aficio SP1000s
# this printer uses SAG-GDI raster format by Sagem Communication
# licence: GPL
# created by palz <paalzza@gmail.com>
# Feb 2011, Moscow, Russia
from struct import *
import sys
from time import time
# parse command-line parameters
if len(sys.argv)<6:
exit(1)
jobid = sys.argv[1]
username = sys.argv[2]
jobtitle = sys.argv[3]
try:
numcopies = int(sys.argv[4])
except:
numcopies = 1
options = sys.argv[5]
filename='-'
if len(sys.argv)>6:
filename=sys.argv[6]
if filename=='.' or filename=='-':
input=sys.stdin
else:
input = open(sys.argv[6],'r')
output = sys.stdout
def print_stderr(s,newline=True):
sys.stderr.write(str(s)+('\n' if newline else ''))
sys.stderr.flush()
#interpret data from CUPS format version 3 supplied via stdin
cups = input.read() # Read all bytes from stdin
sync_word=cups[0:4] # length of sync-word is 4 bytes: "3SaR"
version=int(cups[0])
cups=cups[4:]
dtype={
'C String': {'b': 's','size': 1},
'Unsigned Integer': {'b': 'I','size': 4},
'IEEE Single Precision': {'b': 'f','size': 4},
}
header_length={ # length of page header
1: 420,
2: 1796,
3: 1796,
}
def make_unpack_format(format,begin,end,split_count=1):
return '<'+(str((end-begin+1)/dtype[format]['size']/split_count)+dtype[format]['b'])*split_count
hdr={
1: {}, # version 1 header
2: {}, # version 2-3 header
}
def unpack_header(cups,version):
# unpack v1 page header
hdr[1]['MediaClass'], = unpack(make_unpack_format('C String',0,63),cups[0:63+1]) # Media class string
hdr[1]['MediaColor'], = unpack(make_unpack_format('C String',64,127),cups[64:127+1]) # Media color string
hdr[1]['MediaType'], = unpack(make_unpack_format('C String',128,191),cups[128:191+1]) # Media type string
hdr[1]['OutputType'], = unpack(make_unpack_format('C String',192,255),cups[192:255+1]) # Output type string
hdr[1]['AdvanceDistance'], = unpack(make_unpack_format('Unsigned Integer',256,259),cups[256:259+1]) # 0 to 2<sup>32</sup> - 1 points
hdr[1]['AdvanceMedia'], = unpack(make_unpack_format('Unsigned Integer',260,263),cups[260:263+1]) # 0 = Never advance roll; 1 = Advance roll after file; 2 = Advance roll after job; 3 = Advance roll after set; 4 = Advance roll after page
hdr[1]['Collate'], = unpack(make_unpack_format('Unsigned Integer',264,267),cups[264:267+1]) # 0 = do not collate copies; 1 = collate copies
hdr[1]['CutMedia'], = unpack(make_unpack_format('Unsigned Integer',268,271),cups[268:271+1]) # 0 = Never cut media; 1 = Cut roll after file; 2 = Cut roll after job; 3 = Cut roll after set; 4 = Cut roll after page
hdr[1]['Duplex'], = unpack(make_unpack_format('Unsigned Integer',272,275),cups[272:275+1]) # 0 = Print single-sided; 1 = Print double-sided
hdr[1]['HWResolution'] = unpack(make_unpack_format('Unsigned Integer',276,283),cups[276:283+1]) # Horizontal and vertical resolution in dots-per-inch.
hdr[1]['ImagingBoundingBox'] = unpack(make_unpack_format('Unsigned Integer',284,299),cups[284:299+1]) # Four integers giving the left, bottom, right, and top positions of the page bounding box in points
hdr[1]['InsertSheet'], = unpack(make_unpack_format('Unsigned Integer',300,303),cups[300:303+1]) # 0 = Do not insert separator sheets; 1 = Insert separator sheets
hdr[1]['Jog'], = unpack(make_unpack_format('Unsigned Integer',304,307),cups[304:307+1]) # 0 = Do no jog pages; 1 = Jog pages after file; 2 = Jog pages after job; 3 = Jog pages after set
hdr[1]['LeadingEdge'], = unpack(make_unpack_format('Unsigned Integer',308,311),cups[308:311+1]) # 0 = Top edge is first; 1 = Right edge is first; 2 = Bottom edge is first; 3 = Left edge is first
hdr[1]['Margins'] = unpack(make_unpack_format('Unsigned Integer',312,319),cups[312:319+1]) # Left and bottom origin of image in points
hdr[1]['ManualFeed'], = unpack(make_unpack_format('Unsigned Integer',320,323),cups[320:323+1]) # 0 = Do not manually feed media; 1 = Manually feed media
hdr[1]['MediaPosition'], = unpack(make_unpack_format('Unsigned Integer',324,327),cups[324:327+1]) # Input slot position from 0 to N
hdr[1]['MediaWeight'], = unpack(make_unpack_format('Unsigned Integer',328,331),cups[328:331+1]) # Media weight in grams per meter squared, 0 = printer default
hdr[1]['MirrorPrint'], = unpack(make_unpack_format('Unsigned Integer',332,335),cups[332:335+1]) # 0 = Do not mirror prints; 1 = Mirror prints
hdr[1]['NegativePrint'], = unpack(make_unpack_format('Unsigned Integer',336,339),cups[336:339+1]) # 0 = Do not invert prints; 1 = Invert prints
hdr[1]['NumCopies'], = unpack(make_unpack_format('Unsigned Integer',340,343),cups[340:343+1]) # 0 to 2<sup>32</sup> - 1, 0 = printer default
hdr[1]['Orientation'], = unpack(make_unpack_format('Unsigned Integer',344,347),cups[344:347+1]) # 0 = Do not rotate page; 1 = Rotate page counter-clockwise; 2 = Turn page upside down; 3 = Rotate page clockwise
hdr[1]['OutputFaceUp'], = unpack(make_unpack_format('Unsigned Integer',348,351),cups[348:351+1]) # 0 = Output face down; 1 = Output face up
hdr[1]['PageSize'] = unpack(make_unpack_format('Unsigned Integer',352,359),cups[352:359+1]) # Width and length in points
hdr[1]['Separations'], = unpack(make_unpack_format('Unsigned Integer',360,363),cups[360:363+1]) # 0 = Print composite image; 1 = Print color separations
hdr[1]['TraySwitch'], = unpack(make_unpack_format('Unsigned Integer',364,367),cups[364:367+1]) # 0 = Do not change trays if selected tray is empty; 1 = Change trays if selected tray is empty
hdr[1]['Tumble'], = unpack(make_unpack_format('Unsigned Integer',368,371),cups[368:371+1]) # 0 = Do not rotate even pages when duplexing; 1 = Rotate even pages when duplexing
hdr[1]['cupsWidth'], = unpack(make_unpack_format('Unsigned Integer',372,375),cups[372:375+1]) # Width of page image in pixels
hdr[1]['cupsHeight'], = unpack(make_unpack_format('Unsigned Integer',376,379),cups[376:379+1]) # Height of page image in pixels
hdr[1]['cupsMediaType'], = unpack(make_unpack_format('Unsigned Integer',380,383),cups[380:383+1]) # Driver-specific 0 to 2<sup>32</sup> - 1
hdr[1]['cupsBitsPerColor'], = unpack(make_unpack_format('Unsigned Integer',384,387),cups[384:387+1]) # 1, 2, 4, 8 bits for version 1 raster files; 1, 2, 4, 8, and 16 bits for version 2 raster files
hdr[1]['cupsBitsPerPixel'], = unpack(make_unpack_format('Unsigned Integer',388,391),cups[388:391+1]) # 1 to 32 bits for version 1 raster files; 1 to 64 bits for version 2 raster files
hdr[1]['cupsBytesPerLine'], = unpack(make_unpack_format('Unsigned Integer',392,395),cups[392:395+1]) # 1 to 2<sup>32</sup> - 1 bytes
hdr[1]['cupsColorOrder'], = unpack(make_unpack_format('Unsigned Integer',396,399),cups[396:399+1]) # 0 = chunky pixels (CMYK CMYK CMYK); 1 = banded pixels (CCC MMM YYY KKK); 2 = planar pixels (CCC... MMM... YYY... KKK...)
hdr[1]['cupsColorSpace'], = unpack(make_unpack_format('Unsigned Integer',400,403),cups[400:403+1]) # 0 = gray (device, typically sRGB-based); 1 = RGB (device, typically sRGB); 2 = RGBA (device, typically sRGB); 3 = black; 4 = CMY; 5 = YMC; 6 = CMYK; 7 = YMCK; 8 = KCMY; 9 = KCMYcm; 10 = GMCK; 11 = GMCS; 12 = WHITE; 13 = GOLD; 14 = SILVER; 15 = CIE XYZ; 16 = CIE Lab; 17 = RGBW (sRGB); 18 = sGray (gray using sRGB gamma/white point); 19 = sRGB; 20 = AdobeRGB; 32 = ICC1 (CIE Lab with hint for 1 color); 33 = ICC2 (CIE Lab with hint for 2 colors); 34 = ICC3 (CIE Lab with hint for 3 colors); 35 = ICC4 (CIE Lab with hint for 4 colors); 36 = ICC5 (CIE Lab with hint for 5 colors); 37 = ICC6 (CIE Lab with hint for 6 colors); 38 = ICC7 (CIE Lab with hint for 7 colors); 39 = ICC8 (CIE Lab with hint for 8 colors); 40 = ICC9 (CIE Lab with hint for 9 colors); 41 = ICCA (CIE Lab with hint for 10 colors); 42 = ICCB (CIE Lab with hint for 11 colors); 43 = ICCC (CIE Lab with hint for 12 colors); 44 = ICCD (CIE Lab with hint for 13 colors); 45 = ICCE (CIE Lab with hint for 14 colors); 46 = ICCF (CIE Lab with hint for 15 colors); 48 = Device1 (DeviceN for 1 color); 48 = Device2 (DeviceN for 2 colors); 48 = Device3 (DeviceN for 3 colors); 48 = Device4 (DeviceN for 4 colors); 48 = Device5 (DeviceN for 5 colors); 48 = Device6 (DeviceN for 6 colors); 48 = Device7 (DeviceN for 7 colors); 48 = Device8 (DeviceN for 8 colors); 48 = Device9 (DeviceN for 9 colors); 48 = DeviceA (DeviceN for 10 colors); 48 = DeviceB (DeviceN for 11 colors); 48 = DeviceC (DeviceN for 12 colors); 48 = DeviceD (DeviceN for 13 colors); 48 = DeviceE (DeviceN for 14 colors); 48 = DeviceF (DeviceN for 15 colors)
hdr[1]['cupsCompression'], = unpack(make_unpack_format('Unsigned Integer',404,407),cups[404:407+1]) # Driver-specific 0 to 2<sup>32</sup> - 1
hdr[1]['cupsRowCount'], = unpack(make_unpack_format('Unsigned Integer',408,411),cups[408:411+1]) # Driver-specific 0 to 2<sup>32</sup> - 1
hdr[1]['cupsRowFeed'], = unpack(make_unpack_format('Unsigned Integer',412,415),cups[412:415+1]) # Driver-specific 0 to 2<sup>32</sup> - 1
hdr[1]['cupsRowStep'], = unpack(make_unpack_format('Unsigned Integer',416,419),cups[416:419+1]) # Driver-specific 0 to 2<sup>32</sup> - 1
# unpack v2 page header
if(version>1):
hdr[2]['cupsNumColors'], = unpack(make_unpack_format('Unsigned Integer',420,423),cups[420:423+1]) # 1 to 6 colors
hdr[2]['cupsBorderlessScalingFactor'], = unpack(make_unpack_format('IEEE Single Precision',424,427),cups[424:427+1]) # 0.0 or 1.0 or greater
hdr[2]['cupsPageSize'] = unpack(make_unpack_format('IEEE Single Precision',428,435),cups[428:435+1]) # Width and length in points
hdr[2]['cupsImagingBBox'] = unpack(make_unpack_format('IEEE Single Precision',436,451),cups[436:451+1]) # Four floating point numbers giving the left, bottom, right, and top positions of the page bounding box in points
hdr[2]['cupsInteger'] = unpack(make_unpack_format('Unsigned Integer',452,515),cups[452:515+1]) # 16 driver-defined integer values
hdr[2]['cupsReal'] = unpack(make_unpack_format('IEEE Single Precision',516,579),cups[516:579+1]) # 16 driver-defined floating point values
hdr[2]['cupsString'] = unpack(make_unpack_format('C String',580,1603,16),cups[580:1603+1]) # 16 driver-defined strings
hdr[2]['cupsMarkerType'], = unpack(make_unpack_format('C String',1604,1667),cups[1604:1667+1]) # Ink/toner type string
hdr[2]['cupsRenderingIntent'], = unpack(make_unpack_format('C String',1668,1731),cups[1668:1731+1]) # Color rendering intent string
hdr[2]['cupsPageSizeName'], = unpack(make_unpack_format('C String',1732,1795),cups[1732:1795+1]) # Page size name/keyword string from PPD
return hdr
page_data=''
def get_cups_page():
global cups,page_data
if len(cups):
hdr=unpack_header(cups[:header_length[version]],version)
print_stderr('cupsWidth x cupsHeight: '+str(hdr[1]['cupsWidth'])+' x '+str(hdr[1]['cupsHeight']))
print_stderr('cupsBytesPerLine: '+str(hdr[1]['cupsBytesPerLine']))
print_stderr('cupsBitsPerPixel: '+str(hdr[1]['cupsBitsPerPixel']))
print_stderr('cupsColorOrder: '+str(hdr[1]['cupsColorOrder']))
print_stderr('page size in bytes = '+str(hdr[1]['cupsBytesPerLine']*hdr[1]['cupsHeight']))
page_data=cups[header_length[version]:header_length[version]+hdr[1]['cupsBytesPerLine']*hdr[1]['cupsHeight']]
cups=cups[header_length[version]+len(page_data):]
return True
else:
return False
def make_bytes():
ret=[]
for byte in range(256):
ret.append([
1 if byte&0b10000000 else 0,
1 if byte&0b01000000 else 0,
1 if byte&0b00100000 else 0,
1 if byte&0b00010000 else 0,
1 if byte&0b00001000 else 0,
1 if byte&0b00000100 else 0,
1 if byte&0b00000010 else 0,
1 if byte&0b00000001 else 0,
])
return ret
bytes = make_bytes()
def get_cups_line(y):
numbytes=hdr[1]['cupsBytesPerLine']
w=hdr[1]['cupsWidth']
line=unpack('<'+str(numbytes)+'B',page_data[y*numbytes:(y+1)*numbytes])
ret=[]
extend=ret.extend
for x in range(0,w/8):
extend(bytes[line[x]])
if w%8:
extend(bytes[line[w/8]][:w%8])
return ret
FORMAT_WIDTH=0
FORMAT_HEIGHT=1
FORMAT_LINEFILL=2
FORMAT_INDEX=3
formats = {
'A4': (0x129A,0x1A7A,0x9A4A,0x0000),
'A5': (0x0CE2,0x1276,0xA233,0x0004),
'A6': (0x08E9,0x0CBE,0xA923,0x000E),
'Letter': (0x1324,0x18DC,0xA44C,0x0001),
'Legal': (0x1324,0x1FE4,0xA44C,0x0002),
'B5': (0x1006,0x16CC,0x8640,0x0005),
'B6': (0x0B14,0x0FE2,0x942C,0x000D),
'Monarch': (0x0850,0x10A8,0x9021,0x0008),
# (width,height,linefill,index,)
# LINEFILL is created by common rule 0x129A = 0x9A + 64 * 0x4A
}
def begin_document():
output.write(pack(
'>76sbbHHI',
') SAG-GDI RL;0;0;Comment Copyright Sagem Communication 2005. Version 1.0.0.0',
0x0D,0x0A,
0x1000,0x0200,
0
))
def end_document():
output.write(pack('>3H',0x1400,0,0))
format = 'A4'
def begin_page(page_format='A4',numcopies=1,toner_economy=False):
if not (page_format in formats):
page_format='A4'
global linefill,format
format=page_format
linefill=formats[format][FORMAT_LINEFILL]
output.write(pack(
'<II4H2B3B',
0x000F0011,
int(hdr[1]['MediaPosition']),
0x0404,0,formats[format][FORMAT_WIDTH],formats[format][FORMAT_HEIGHT],
formats[format][FORMAT_INDEX],int(hdr[1]['cupsMediaType']),
numcopies,0,1 if toner_economy else 0
))
def end_page():
output.write(pack('>3H',0x1300,0,0))
current_block_data=''
current_line_length=0
def begin_block():
global current_block_data
current_block_data=''
def get_block_size():
return len(current_block_data)
def end_block():
output.write(pack('<3H',0x0012,get_block_size(),0)+current_block_data)
def write_px_data(col,length):
if length<=0:
return
color = 1 if col else 0
color_bit = color << 6
first_byte = length%64
second_byte = length/64
two_bytes_bit = 0b10000000 if second_byte else 0b00000000
px_data=pack('>B', two_bytes_bit | color_bit | first_byte)
if second_byte:
px_data=px_data+pack('>B',second_byte)
# start new block of commands if previous is full
if len(px_data)+get_block_size()>0xFF:
end_block()
begin_block()
global current_line_length,current_block_data
current_block_data+=px_data
current_line_length+=length
def fill_line():
global current_line_length
write_px_data(0,formats[format][FORMAT_WIDTH]-current_line_length)
current_line_length=0
def write_cups():
w,h=min(hdr[1]['cupsWidth'],formats[format][FORMAT_WIDTH]),min(hdr[1]['cupsHeight'],formats[format][FORMAT_HEIGHT])
t=time()
for y in range(h):
if y%(h/15)==0:
print_stderr('%d%% '%(int(float(y)/h*100),),False)
yline=get_cups_line(y)
lastcol=yline[0]
lastcolidx=0
for x in range(1,w):
currcol=yline[x] # 1 means black pixel
if (currcol!=lastcol):
write_px_data(lastcol,x-lastcolidx)
lastcol=currcol
lastcolidx=x
write_px_data(lastcol,w-lastcolidx)
fill_line() # fills rest of the line and resets current_line_length
if h<formats[format][FORMAT_HEIGHT]:
for y in range(h,formats[format][FORMAT_HEIGHT]):
fill_line()
print_stderr('100%%.\nDone in %.3f seconds.'%(time()-t,))
begin_document()
curr_page_number=0
while get_cups_page():
begin_page(hdr[2]['cupsPageSizeName'][:2],numcopies=numcopies)
begin_block()
curr_page_number+=1
print_stderr('Rendering page %i'%(curr_page_number,))
write_cups()
end_block()
end_page()
end_document()
|