The attached file doesn't disassemble with pxldis.py. . . . ubyte 0 // Op Pos: 11 Op fOff: 849 Op Hex: 98 Level: 0 Ellipse uint32 262144 // Op Pos: 12 Op fOff: 856 Op Hex: 95 Level: 0 BezierRelPath uint32 824 // Op Pos: 13 Op fOff: 863 Op Hex: 92 Level: 0 SetColorTrapping // Op Pos: 14 Op fOff: 864 Op Hex: 46 Level: 0 VendorUnique dissassemble failed at file position 169 0x0 0x80 0x0 0x3 0x0 0x0 0x2 0x0 0x0 0x0 0x3 0x0 0x0 0x0 0x4 0x0 0x0 0x0 0x5 0x0 0x0 0x0 0x5 0x0 0x0
Created attachment 4406 [details] test.prn
Yes, this a known problem. HP is now using a private undocumented operator "VendorUnique" which we correctly skip over on some devices (e.g. hp 4600), I haven't analyzed this printer's (Color Laserjet 3600) implementation of the operator. Hin Tak may have information about this printer so I copied him in and made the problem bountiable. In this case simply providing documentation for the operator is enough to collect the bounty, no code changes are needed.
I have a private mod of pxldis.py which disassembles the vendorunique operators, actually. So this is right in my area.
Oh, the private mod of pxldis.py fairly ugly and has a few extra things, and some are not compatible changes - but I'll dig it up and see what can be merged back upstream.
> Oh, the private mod of pxldis.py fairly ugly and has a few extra things, and > some are not compatible changes - but I'll dig it up and see what can be merged > back upstream. Feel free to post what you have, if is useful to solving the problem you will still get the bounty.
Created attachment 4495 [details] Here is my pxldis.py script Here is my pxldis.py variant. I have quickly removed some detailed hex-dump stuff for the vendorunique data which probably isn't too interesting to others (they are too large and not interesting to be hex-dumped in-line of the PCL-XL so I there is code to put it away to be hex-dumped after the whole stream is processed, and I have removed the post-processing bit). It works on attachment 4406 [details] correctly, but I don't know if it works on "normal" PCL-XL any more. (I think it does, but I am not sure). Besides the venorunique operators, it also have two additional changes: - runs on 64-bit python as well as 32-bit python (some L/l should be I/i) - the original hexdump was too slow and memory consuming for files with large embedded data - this has a faster/less-hungry hex-dump code. Main-line pxldis.py has moved on a bit, so it will take some time to sort it out.
So I'll integrate the changes one at a time. For this one: > - runs on 64-bit python as well as 32-bit python (some L/l should be I/i) I think there is more to be done, against http://svn.ghostscript.com/ghostscript/trunk/ghostpdl/tools/pxldis.py: =================================================================== --- pxldis.py (revision 9129) +++ pxldis.py (working copy) @@ -443,7 +443,7 @@ if ( new_tag == pxl_tags_dict['sint32'] ): self.index = self.index + 1 print "sint32", - self.unpack_string = 'l' + self.unpack_string = 'i' self.size_of_element = 4 return 1 return 0 @@ -455,7 +455,7 @@ self.index = self.index + 1 print "uint32", - self.unpack_string = 'L' + self.unpack_string = 'I' self.size_of_element = 4 return 1 return 0 @@ -509,7 +509,7 @@ if ( new_tag == pxl_tags_dict['uint32_array'] ): self.index = self.index + 1 - self.unpack_string = 'L' + self.unpack_string = 'I' self.size_of_element = 4 print "uint32_array [", return 1 @@ -520,7 +520,7 @@ if ( new_tag == pxl_tags_dict['sint32_array'] ): self.index = self.index + 1 - self.unpack_string = 'l' + self.unpack_string = 'i' self.size_of_element = 4 print "sint32_array [", return 1 @@ -580,7 +580,7 @@ self.index = self.index + 1 print "uint32_xy" % \ - self.unpack('LL', self.data[self.index:self.index+8]), + self.unpack('II', self.data[self.index:self.index+8]), self.index = self.index + 8 return 1 return 0 @@ -592,7 +592,7 @@ self.index = self.index + 1 print "sint32_xy %d %d" % \ - self.unpack('ll', self.data[self.index:self.index+8]), + self.unpack('ii', self.data[self.index:self.index+8]), self.index = self.index + 8 return 1 return 0 @@ -647,7 +647,7 @@ if ( new_tag == pxl_tags_dict['uint32_box'] ): self.index = self.index + 1 print "uint32_box %d %d %d %d" % \ - self.unpack('LLLL', self.data[self.index:self.index+16]) + self.unpack('IIII', self.data[self.index:self.index+16]) self.index = self.index + 32 return 1 return 0 @@ -659,7 +659,7 @@ self.index = self.index + 1 print "sint32_box %d %d %d %d" % \ - self.unpack('llll', self.data[self.index:self.index+16]) + self.unpack('iiii', self.data[self.index:self.index+16]) self.index = self.index + 16 return 1 return 0
Created attachment 4500 [details] the diff of my pxldis.py variant against its ancestor This is the diff of my pxldis.py variant against its ancestor (an older version of upstream pxldis.py). Hope this is clearer about what was changed. There is one more some what cosmetic change to do with user broken pipe. (i.e. when the user do "pxldis.py somefile |more", but then decided to stop because of too much embedded info).
Clearing the bountiable status since it was already claimed. 64-bit change in comment 7 was committed as r9166, and the hexdump improvement mentioned in comment 6 was committed as r10183 . Grabbing the bug myself to integrate the rest of the change, if any, since I am working on the same code area with bug 691146 anyway.
The rest of the pxldis diff has been integrated as r10856 r10857 r10858 r10859 r10860 r10861 r10862 r10863 r10865 . r10859 (+ r10865) implements disassembling of the VUDataLength embedded payload (which is AFAIK CLJ3500/3550/3600-specific); the requires the corresponding change r10866 to assemble. The pair of scripts in r10866 should be able to do round-trip assemble/disassemble correctly. Use http://bugs.ghostscript.com/attachment.cgi?id=6033 in bug 691146 for checking round-trip correctness.