initial commit
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Explain the retained failing CMYK comparison without relaxing its criterion."""
|
||||
from io import BytesIO
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image, ImageCms
|
||||
from pypdf import PdfReader
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
RESULTS = ROOT / 'tests/results/cmyk-lut'
|
||||
|
||||
|
||||
def sha(path):
|
||||
with path.open('rb') as stream:
|
||||
return hashlib.file_digest(stream, 'sha256').hexdigest()
|
||||
|
||||
|
||||
def main():
|
||||
corpus=ROOT/'tests/fixtures/pdf/cmyk-lut'
|
||||
spec=json.loads((corpus/'manifest.json').read_text())
|
||||
pdf=PdfReader(corpus/spec['file'])
|
||||
assert b'/RelativeColorimetric ri' in pdf.pages[0].get_contents().get_data()
|
||||
assert pdf.pages[0]['/Resources']['/XObject']['/Sample']['/Intent']=='/RelativeColorimetric'
|
||||
source=json.loads((RESULTS/'pdfium-source/record.json').read_text())
|
||||
for row in source['files']:
|
||||
assert sha(RESULTS/'pdfium-source'/row['path'])==row['sha256']
|
||||
transform_source=(RESULTS/'pdfium-source/core/fxcodec/icc/icc_transform.cpp').read_text()
|
||||
assert 'TYPE_BGR_8, INTENT_PERCEPTUAL, /*dwFlags=*/0' in transform_source
|
||||
profile=ImageCms.ImageCmsProfile(BytesIO((corpus/spec['profileFile']).read_bytes()))
|
||||
transformations={intent:ImageCms.buildTransformFromOpenProfiles(profile,ImageCms.createProfile('sRGB'),
|
||||
'CMYK','RGB',renderingIntent=value) for intent,value in [('perceptual',0),('relative',1)]}
|
||||
colors={}
|
||||
for probe in spec['probes']:
|
||||
if probe['kind']!='icc-image': continue
|
||||
pixel=Image.new('CMYK',(1,1),tuple(round(c*255) for c in probe['components']))
|
||||
colors[probe['sample']]={name:list(ImageCms.applyTransform(pixel,t).getpixel((0,0))) for name,t in transformations.items()}
|
||||
rows=[]
|
||||
for os_name in ('arch','ubuntu'):
|
||||
report=json.loads((RESULTS/os_name/'report.json').read_text())
|
||||
assert not report['success'] and report['fixture']['sha256']==spec['sha256']
|
||||
assert report['originalUnchanged'] and report['binariesUnchanged']
|
||||
assert report['runnerSha256']==sha(ROOT/'tests/cmyk_lut/run.py')
|
||||
for name,digest in report['evidenceSha256'].items():
|
||||
assert sha(RESULTS/os_name/name)==digest
|
||||
failed=0; matches=[]
|
||||
for scale in report['scales']:
|
||||
failed+=sum(not p['success'] for p in scale['probes'])
|
||||
for probe in scale['probes']:
|
||||
if probe['kind']!='icc-image': continue
|
||||
pair=colors[probe['sample']]
|
||||
errors={name:max(abs(a-b) for a,b in zip(probe['actualRgb'][name],pair[intent]))
|
||||
for name,intent in [('pdfium','perceptual'),('poppler','relative')]}
|
||||
matches.append({'scale':scale['scale'],'sample':probe['sample'],'actualRgb':probe['actualRgb'],
|
||||
'cmmIntentColors':pair,'errorsAgainstRespectiveIntent':errors})
|
||||
failed_by_renderer={name:sum(p['maxChannelError'].get(name,0)>spec['tolerance8Bit']
|
||||
for scale in report['scales'] for p in scale['probes'])
|
||||
for name in ('pdfium','poppler')}
|
||||
maximum=max(p['maxChannelError'].get('pdfium',0) for scale in report['scales'] for p in scale['probes'])
|
||||
assert failed==failed_by_renderer['pdfium']==30 and failed_by_renderer['poppler']==0 and maximum==74
|
||||
assert all(max(m['errorsAgainstRespectiveIntent'].values())<=1 for m in matches)
|
||||
rows.append({'os':os_name,'comparisonReportSha256':sha(RESULTS/os_name/'report.json'),
|
||||
'analyticProbes':48,'failedPdfiumAnalyticProbes':failed,'failedPopplerAnalyticProbes':failed_by_renderer['poppler'],
|
||||
'maximumPdfiumAnalyticChannelDifference':maximum,'intentMatchedImageProbes':matches})
|
||||
result={'diagnosisVerified':True,'renderingAcceptance':False,'relativeIntentPreserved':False,
|
||||
'toleranceUnchanged':spec['tolerance8Bit'],'profileSha256':spec['profileSha256'],
|
||||
'sourceRevision':source['revision'],'sourceEvidenceSha256':sha(RESULTS/'pdfium-source/record.json'),
|
||||
'diagnoserSha256':sha(Path(__file__)),'cmmVersion':ImageCms.core.littlecms_version,'results':rows,
|
||||
'finding':'At this fixed PDFium revision, ICC conversion selects INTENT_PERCEPTUAL regardless of the '
|
||||
'relative-colorimetric intent in the test PDF. On both OSs, all eight image swatches at all '
|
||||
'three scales match LittleCMS perceptual output within one channel level. Poppler matches '
|
||||
'relative-colorimetric output. This explains, but does not accept or repair, the difference.',
|
||||
'remaining':'G-RENDER requires review and resolution/explicit compatibility judgment. No renderer '
|
||||
'patch, engine substitution or user-visible detection was implemented in this comparison.'}
|
||||
(RESULTS/'diagnosis.json').write_text(json.dumps(result,indent=2)+'\n')
|
||||
print(json.dumps({'diagnosisVerified':True,'renderingAcceptance':False,'failedAnalyticProbes':60,
|
||||
'intentMatchedImageProbes':48}))
|
||||
|
||||
|
||||
if __name__=='__main__': main()
|
||||
Reference in New Issue
Block a user