initial commit
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate finite, original high-resolution raster and transparent-vector pages."""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import zlib
|
||||
|
||||
|
||||
def generate(path):
|
||||
path = Path(path)
|
||||
if path.exists():
|
||||
raise FileExistsError(path)
|
||||
width, height, curves = 4960, 7016, 60000
|
||||
compressor = zlib.compressobj(6)
|
||||
chunks = []
|
||||
raw_hash = hashlib.sha256()
|
||||
# Bounded row buffer; 104,398,080 decoded RGB bytes, about A4 at 600 dpi.
|
||||
paper = bytes((248, 246, 240)) * width
|
||||
text_row = b''.join(bytes((35, 40, 48)) if 260 < x < width - 260 and x % 83 < 61
|
||||
else bytes((248, 246, 240)) for x in range(width))
|
||||
for y in range(height):
|
||||
row = text_row if 500 < y < height - 500 and y % 123 < 35 else paper
|
||||
raw_hash.update(row)
|
||||
part = compressor.compress(row)
|
||||
if part:
|
||||
chunks.append(part)
|
||||
chunks.append(compressor.flush())
|
||||
image = b''.join(chunks)
|
||||
vector = [b'q 20 20 555 802 re W n /GS gs\n']
|
||||
for index in range(curves):
|
||||
x, y = 25 + (index * 37) % 490, 30 + (index * 53) % 730
|
||||
r, g, b = (index % 7) / 7, (index % 11) / 11, (index % 13) / 13
|
||||
vector.append((f'{r:.3f} {g:.3f} {b:.3f} rg {x} {y} m '
|
||||
f'{x+38} {y+67} {x+61} {y-19} {x+69} {y+22} c '
|
||||
f'{x+25} {y+48} l h f\n').encode())
|
||||
vector.append(b'Q\n0.85 0.1 0.65 rg 30 780 32 32 re f\n'
|
||||
b'BT /F1 12 Tf 80 790 Td (DOCVIEW COMPLEX 60000 TRANSPARENT PATHS) Tj ET\n')
|
||||
content = [b'q 555 0 0 782 20 20 cm /Scan Do Q\n'
|
||||
b'0.1 0.3 0.6 rg 30 780 32 32 re f\n'
|
||||
b'BT /F1 12 Tf 80 790 Td (DOCVIEW RASTER 4960 x 7016 RGB) Tj ET\n',
|
||||
b''.join(vector)]
|
||||
def stream(data, dictionary=b''):
|
||||
return dictionary + b' /Length ' + str(len(data)).encode() + b' >>\nstream\n' + data + b'\nendstream'
|
||||
objects = [b'<< /Type /Catalog /Pages 2 0 R >>',
|
||||
b'<< /Type /Pages /Count 2 /Kids [7 0 R 9 0 R] >>',
|
||||
b'<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>',
|
||||
stream(image, f'<< /Type /XObject /Subtype /Image /Width {width} /Height {height} /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /FlateDecode'.encode()),
|
||||
b'<< /Type /ExtGState /ca 0.16 /CA 0.16 /BM /Multiply >>',
|
||||
stream(zlib.compress(content[0]), b'<< /Filter /FlateDecode'),
|
||||
b'<< /Type /Page /Parent 2 0 R /MediaBox [0 0 595 842] /Resources << /Font << /F1 3 0 R >> /XObject << /Scan 4 0 R >> >> /Contents 6 0 R >>',
|
||||
stream(zlib.compress(content[1]), b'<< /Filter /FlateDecode'),
|
||||
b'<< /Type /Page /Parent 2 0 R /MediaBox [0 0 595 842] /Resources << /Font << /F1 3 0 R >> /ExtGState << /GS 5 0 R >> >> /Contents 8 0 R >>']
|
||||
offsets = [0]
|
||||
with path.open('xb') as out:
|
||||
out.write(b'%PDF-1.7\n%\xe2\xe3\xcf\xd3\n')
|
||||
for index, data in enumerate(objects, 1):
|
||||
offsets.append(out.tell())
|
||||
out.write(f'{index} 0 obj\n'.encode() + data + b'\nendobj\n')
|
||||
xref = out.tell()
|
||||
out.write(f'xref\n0 {len(offsets)}\n0000000000 65535 f \n'.encode())
|
||||
for offset in offsets[1:]:
|
||||
out.write(f'{offset:010d} 00000 n \n'.encode())
|
||||
out.write(f'trailer\n<< /Root 1 0 R /Size {len(offsets)} >>\nstartxref\n{xref}\n%%EOF\n'.encode())
|
||||
return {'sha256': hashlib.sha256(path.read_bytes()).hexdigest(), 'sizeBytes': path.stat().st_size,
|
||||
'pages': 2, 'rasterWidth': width, 'rasterHeight': height, 'decodedRasterBytes': width * height * 3,
|
||||
'rasterSha256': raw_hash.hexdigest(), 'transparentPathCount': curves,
|
||||
'rasterFilter': 'FlateDecode', 'vectorAlpha': 0.16, 'vectorBlendMode': 'Multiply',
|
||||
'source': 'Original deterministic synthetic fixture; standard Helvetica is not embedded',
|
||||
'scope': 'One 600-dpi-equivalent image and one dense transparent-vector page, not a full book or real scan corpus'}
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('output', type=Path)
|
||||
args = parser.parse_args()
|
||||
manifest = generate(args.output)
|
||||
args.output.with_suffix('.json').write_text(json.dumps(manifest, indent=2) + '\n')
|
||||
print(json.dumps(manifest))
|
||||
Reference in New Issue
Block a user