Publish 39 reviewed original terrain HD remasters

This commit is contained in:
raptorreplica committed 2026-10-20 20:43:40 +11:00
1 parent 884944e8ea
commit b2e19b8b86
8019 files changed
+4597161 -99

No files matched your search

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,411 @@
"""Private Source-shaped genuine-RGB derivation proposal. Never a generator return.
The single32x32 opaque format is decoded here honestly, including protected labels;
the ordinary-only decoder in hd_terrain_cleanup is neither called nor bypassed.
"""
from pathlib import Path
import argparse, hashlib, json, sys, struct, os, stat, io
import numpy as np
from PIL import Image
ROOT=next((p for p in Path(__file__).resolve().parents if (p/'tools/hd_terrain_cleanup.py').is_file()),None)
if ROOT is None: raise RuntimeError('place this portable helper under the game root containing tools/hd_terrain_cleanup.py')
MAX_INPUT_BYTES=16*1024*1024
MAX_RECIPE_BYTES=64*1024
MAX_PNG_PIXELS=4*1024*1024
def read_contained(root,relative,limit=MAX_INPUT_BYTES):
if not isinstance(relative,str) or relative.startswith('/') or any(x in ('','.','..') for x in relative.split('/')):
raise ValueError('strict contained relative path required')
root=Path(root).absolute()
if '..' in root.parts:raise ValueError('noncanonical root path')
flags=os.O_RDONLY|os.O_CLOEXEC|os.O_NOFOLLOW|os.O_NONBLOCK
fd=os.open('/',flags|os.O_DIRECTORY)
try:
for part in root.parts[1:]+tuple(relative.split('/')[:-1]):
following=os.open(part,flags|os.O_DIRECTORY,dir_fd=fd);os.close(fd);fd=following
source=os.open(relative.split('/')[-1],flags,dir_fd=fd)
try:
before=os.fstat(source)
if not stat.S_ISREG(before.st_mode) or not 0<=before.st_size<=limit:raise ValueError('regular bounded input required')
chunks=[];size=0
while True:
chunk=os.read(source,min(65536,limit+1-size))
if not chunk:break
chunks.append(chunk);size+=len(chunk)
if size>limit:raise ValueError('bounded EOF limit exceeded')
after=os.fstat(source)
identity=lambda x:(x.st_dev,x.st_ino,x.st_size,x.st_mtime_ns,x.st_mode)
if identity(before)!=identity(after) or size!=before.st_size:raise ValueError('input changed or non-EOF read')
payload=b''.join(chunks)
return payload,dict(path=str(root/relative),sha256=hashlib.sha256(payload).hexdigest(),size=size,mtime_ns=before.st_mtime_ns,mode=before.st_mode)
finally:os.close(source)
finally:os.close(fd)
class BufferedInputs:
def __init__(self,root):self.root=Path(root);self.cache={};self.physical_reads=0
def read(self,binding):
rel=binding['path']
if rel not in self.cache:
self.cache[rel]=read_contained(self.root,rel);self.physical_reads+=1
payload,pin=self.cache[rel]
if pin['sha256']!=binding['sha256']:raise ValueError('input SHA mismatch')
return payload,pin
def decode_png(payload):
if len(payload)>MAX_INPUT_BYTES:raise ValueError('encoded PNG too large')
with Image.open(io.BytesIO(payload)) as im:
if im.format!='PNG' or im.width<1 or im.height<1 or im.width*im.height>MAX_PNG_PIXELS:raise ValueError('bounded PNG required')
if getattr(im,'n_frames',1)!=1 or im.mode not in ('RGB','RGBA'):raise ValueError('single RGB/RGBA PNG required')
if im.mode=='RGBA' and im.getchannel('A').getextrema()!=(255,255):raise ValueError('opaque PNG donor required')
return np.array(im.convert('RGB'))
EXPECTED_DEPENDENCY_SHA256='3284cf6f85ced107dfc364ea90e15aed341d478bea7e308024b5bc5218b03092'
_dependency_bytes,_dependency_pin=read_contained(ROOT/'tools','hd_terrain_cleanup.py',1024*1024)
if _dependency_pin['sha256']!=EXPECTED_DEPENDENCY_SHA256:raise RuntimeError('reviewed terrain math dependency changed')
_dependency_namespace={'__name__':'reviewed_component_terrain_math','__file__':str(ROOT/'tools/hd_terrain_cleanup.py')}
exec(compile(_dependency_bytes,_dependency_namespace['__file__'],'exec'),_dependency_namespace)
scale_nx,gaussian,resize_float,palette_rgb=(_dependency_namespace[x]for x in ('scale_nx','gaussian','resize_float','palette_rgb'))
PAIR_IDS=('103d5','103d6')
METHOD='Source-shape-component-material-RGB-band-and-finite-T-landmark-warp-v1'
def decode_source32(payload):
if len(payload)!=1044 or struct.unpack_from('<5i',payload)!=(1,1,0,32,32):
raise ValueError('requires exact opaque single32x32 Source PIC')
return np.frombuffer(payload[20:],np.uint8).reshape(32,32).copy()
def material_labels(indices,approach_rows):
a=np.asarray(indices)
if a.ndim!=2 or a.dtype!=np.uint8 or not 0<=approach_rows<=a.shape[0]:
raise ValueError('requires an indexed plane and bounded approach rows')
out=np.full(a.shape,-1,np.int8)
out[((a>=149)&(a<=159))|((a>=240)&(a<=244))]=0 # water and actual water cycling only
out[(a<32)|(a==173)]=1 # grey rail/shadow
out[((a>=182)&(a<=190))|((a>=192)&(a<=218))]=2 # red bank / edge earth
out[(a>=219)&(a<=238)]=3 # deck; upper approach separately registered
if np.any(out<0): raise ValueError('unsupported Source material or protected class')
out[:approach_rows][out[:approach_rows]==3]=4
return out
def donor_field(rgb,box,size,tile_size=None):
if len(box)!=4 or any(type(v)is not int for v in box):raise ValueError('integer donor box required')
x,y,w,h=box
if min(x,y)<0 or min(w,h)<1 or x+w>rgb.shape[1]or y+h>rgb.shape[0]:raise ValueError('donor crop outside genuine image')
im=Image.fromarray(rgb[y:y+h,x:x+w])
if tile_size:
sw,sh=tile_size
if min(sw,sh)<1:raise ValueError('bad texture period')
tile=np.array(im.resize((sw,sh),Image.Resampling.LANCZOS))
return np.tile(tile,(int(np.ceil(size[1]/sh)),int(np.ceil(size[0]/sw)),1))[:size[1],:size[0]].astype(float)
return np.array(im.resize(size,Image.Resampling.LANCZOS),dtype=float)
def derive_pair(sources,palette,fields,audit=None):
if len(sources)!=2 or set(fields)!=set(range(5)):raise ValueError('complete pair and all five donor components required')
guide=np.concatenate([scale_nx(x,4)for x in sources],axis=1)
# Material ownership is classified FROM the exact SourceNx index plane, not independently scaled label edges.
labels=material_labels(guide,48)
owners=np.repeat(np.repeat(labels,4,0),4,1)
source_rgb=palette[guide].astype(float);output=np.zeros((512,1024,3),float);base_output=np.zeros_like(output)
for component in range(5):
mask=(labels==component).astype(float)
weight=resize_float(gaussian(mask,1.0),(1024,512))
numerator=resize_float(gaussian(source_rgb*mask[...,None],1.0),(1024,512))
base=numerator/np.maximum(weight[...,None],1e-12)
donor=np.asarray(fields[component],float)
if donor.shape!=output.shape:raise ValueError('registered donor field size mismatch')
# Preserve genuine bounded RGB texture, never donor coarse shape/color drift.
band=np.clip(donor-gaussian(donor,8.0),-26,26)*0.75
output[owners==component]=(base+band)[owners==component]
base_output[owners==component]=base[owners==component]
output=np.clip(np.rint(output),0,255).astype(np.uint8)
protected=np.repeat(np.repeat(guide>=240,4,0),4,1)
exact=np.repeat(np.repeat(palette[guide],4,0),4,1)
output[protected]=exact[protected]
base8=np.clip(np.rint(base_output),0,255).astype(np.uint8)
if audit is not None:
audit.update(genuine_RGB_band_changed_nonfunctional_pixels=int(np.any(output!=base8,axis=2)[~protected].sum()),nonfunctional_pixels=int((~protected).sum()))
return output,owners,protected,guide
def validate_knots(knots):
if len(knots)<2 or knots[0]!=0 or knots[-1]!=1 or any(not np.isfinite(x)for x in knots)or any(a>=b for a,b in zip(knots,knots[1:])):raise ValueError('strict finite0..1 knot partition required')
def warp_landmarks(rgb,tx,ty,sx,sy):
for knots in (tx,ty,sx,sy):validate_knots(knots)
if len(tx)!=len(sx)or len(ty)!=len(sy):raise ValueError('paired knot counts required')
h,w,_=rgb.shape;mesh=[]
xs=[round(v*w)for v in tx];ys=[round(v*h)for v in ty]
for yi in range(len(ty)-1):
for xi in range(len(tx)-1):
rect=(xs[xi],ys[yi],xs[xi+1],ys[yi+1])
if rect[2]<=rect[0]or rect[3]<=rect[1]:raise ValueError('empty mesh cell')
l,r=sx[xi]*w,sx[xi+1]*w;t,b=sy[yi]*h,sy[yi+1]*h
mesh.append((rect,(l,t,l,b,r,b,r,t)))
return np.array(Image.fromarray(rgb).transform((w,h),Image.Transform.MESH,mesh,Image.Resampling.BICUBIC))
NINE_IDS={'10502','10504','10506','10508','10509','1050a','1050b','1050c','1050e'}
COHORTS={('10502','10506','10508','10509','1050a'),('10504','1050b','1050c','1050e')}
def nine_material_labels(a):
a=np.asarray(a)
if a.ndim!=2 or a.dtype!=np.uint8:raise ValueError('indexed Source plane required')
labels=np.full(a.shape,-1,np.int8)
labels[((a>=148)&(a<=159))|((a>=240)&(a<=244))]=0
labels[(a<32)|(a==173)]=1
labels[(a>=182)&(a<=218)]=2
labels[(a>=219)&(a<=239)]=3
labels[(a>=80)&(a<=95)]=4
labels[a>=245]=5 # exact protected fire/individual, never ordinary material
if np.any(labels<0):raise ValueError('unsupported actual Source material')
return labels
def functional_support_union(indices):
if indices.shape!=(32,32)or indices.dtype!=np.uint8:raise ValueError('exact Source32 plane required')
cells=set()
for factor in range(1,5):
y,x=np.where(scale_nx(indices,factor)>=240)
cells.update((int(xx)//factor,int(yy)//factor)for xx,yy in zip(x,y))
return [list(p)for p in sorted(cells)]
def derive_nine_tile(indices,palette,fields):
if set(fields)!=set(range(5)):raise ValueError('five genuine material donor fields required')
if indices.shape!=(32,32)or indices.dtype!=np.uint8:raise ValueError('exact Source32 plane required')
guide=scale_nx(indices,4);labels=nine_material_labels(guide)
owners=np.repeat(np.repeat(labels,4,0),4,1)
source_rgb=palette[guide].astype(float);output=np.zeros((512,512,3),float);base_output=np.zeros_like(output)
for component in range(5):
mask=(labels==component).astype(float)
if not np.any(mask):continue
weights=resize_float(gaussian(mask,1.0),(512,512))
numerator=resize_float(gaussian(source_rgb*mask[...,None],1.0),(512,512))
base=numerator/np.maximum(weights[...,None],1e-12)
donor=np.asarray(fields[component],float)
if donor.shape!=output.shape:raise ValueError('registered donor field size mismatch')
band=np.clip(donor-gaussian(donor,8.0),-26,26)*0.75
output[owners==component]=(base+band)[owners==component]
base_output[owners==component]=base[owners==component]
output=np.clip(np.rint(output),0,255).astype(np.uint8)
exact=np.repeat(np.repeat(palette[guide],4,0),4,1);protected=np.repeat(np.repeat(guide>=240,4,0),4,1)
output[protected]=exact[protected]
# All logical owners that contain any Scale1..4 functional support are excluded from HD credit.
union=functional_support_union(indices);retained=np.zeros((32,32),bool)
for x,y in union:retained[y,x]=True
owner_retained=np.repeat(np.repeat(retained,16,0),16,1)
base8=np.clip(np.rint(base_output),0,255).astype(np.uint8)
changed=int(np.any(output!=base8,axis=2)[~owner_retained].sum())
if changed==0:raise ValueError('no surviving genuine generated RGB contribution; Original-only is not HD')
metrics={'original_detail_cells':union,'raw_Source_reserved_cells':int((indices>=240).sum()),'functional_support_union_cells':len(union),'all_functional_SourceNx_RGB_exact':bool(np.array_equal(output[protected],exact[protected])),'nonfunctional_HDR_pixels':int((~owner_retained).sum()),'genuine_RGB_band_changed_nonfunctional_HDR_pixels':changed,'geometry_owner_sha256':hashlib.sha256(owners.tobytes()).hexdigest(),'Original_functional_HD_credit':0}
return output,owners,protected,metrics
NEXT_PAIR_IDS=('10536','1053e')
def next_pair_material_labels(a):
a=np.asarray(a)
if a.ndim!=2 or a.dtype!=np.uint8:raise ValueError('indexed Source plane required')
labels=np.full(a.shape,-1,np.int8)
labels[((a>=148)&(a<=159))|((a>=240)&(a<=244))]=0
labels[a<32]=1
labels[(a>=182)&(a<=239)]=2
labels[(a==65)|((a>=80)&(a<=95))]=3
labels[np.isin(a,[34,38,39,42,43,44])]=4
labels[a>=245]=5
if np.any(labels<0):raise ValueError('unsupported actual next-pair Source material')
return labels
def derive_next_pair_tile(indices,palette,fields):
if set(fields)!=set(range(5)):raise ValueError('five genuine material donor fields required')
if indices.shape!=(32,32)or indices.dtype!=np.uint8:raise ValueError('exact Source32 plane required')
guide=scale_nx(indices,4);labels=next_pair_material_labels(guide)
owners=np.repeat(np.repeat(labels,4,0),4,1)
source_rgb=palette[guide].astype(float);output=np.zeros((512,512,3),float);base_output=np.zeros_like(output)
for component in range(5):
mask=(labels==component).astype(float)
if not np.any(mask):continue
weights=resize_float(gaussian(mask,1.0),(512,512))
numerator=resize_float(gaussian(source_rgb*mask[...,None],1.0),(512,512))
base=numerator/np.maximum(weights[...,None],1e-12)
donor=np.asarray(fields[component],float)
if donor.shape!=output.shape:raise ValueError('registered donor field size mismatch')
band=np.clip(donor-gaussian(donor,3.0),-16,16)*0.5
output[owners==component]=(base+band)[owners==component]
base_output[owners==component]=base[owners==component]
output=np.clip(np.rint(output),0,255).astype(np.uint8)
exact=np.repeat(np.repeat(palette[guide],4,0),4,1);protected=np.repeat(np.repeat(guide>=240,4,0),4,1)
output[protected]=exact[protected]
# All logical owners that contain any Scale1..4 functional support are excluded from HD credit.
union=functional_support_union(indices);retained=np.zeros((32,32),bool)
for x,y in union:retained[y,x]=True
owner_retained=np.repeat(np.repeat(retained,16,0),16,1)
base8=np.clip(np.rint(base_output),0,255).astype(np.uint8)
changed=int(np.any(output!=base8,axis=2)[~owner_retained].sum())
if changed==0:raise ValueError('no surviving genuine generated RGB contribution; Original-only is not HD')
metrics={'original_detail_cells':union,'raw_Source_reserved_cells':int((indices>=240).sum()),'functional_support_union_cells':len(union),'all_functional_SourceNx_RGB_exact':bool(np.array_equal(output[protected],exact[protected])),'nonfunctional_HDR_pixels':int((~owner_retained).sum()),'genuine_RGB_band_changed_nonfunctional_HDR_pixels':changed,'geometry_owner_sha256':hashlib.sha256(owners.tobytes()).hexdigest(),'Original_functional_HD_credit':0}
return output,owners,protected,metrics
SINGLETON_IDS={'1054f','10561'}
def singleton_material_labels(a):
a=np.asarray(a)
if a.ndim!=2 or a.dtype!=np.uint8:raise ValueError('indexed Source plane required')
labels=np.full(a.shape,-1,np.int8)
labels[(a>=148)&(a<=159)]=0
labels[a<32]=1
labels[(a>=182)&(a<=239)]=2
labels[np.isin(a,[69,70,73,75])|((a>=80)&(a<=95))]=3
labels[np.isin(a,[38,39,40,41,42,43])]=4
labels[(a>=240)|(a==102)]=5 # exact Source functional/isolated green fixture retention
if np.any(labels<0):raise ValueError('unsupported actual singleton Source material')
return labels
def singleton_fidelity_union(indices):
if indices.shape!=(32,32)or indices.dtype!=np.uint8:raise ValueError('exact Source32 plane required')
cells=set()
for factor in range(1,5):
plane=scale_nx(indices,factor);y,x=np.where((plane>=240)|(plane==102))
cells.update((int(xx)//factor,int(yy)//factor)for xx,yy in zip(x,y))
return [list(p)for p in sorted(cells)]
def derive_singleton_tile(indices,palette,fields):
if set(fields)!=set(range(5)):raise ValueError('five genuine material donor fields required')
if indices.shape!=(32,32)or indices.dtype!=np.uint8:raise ValueError('exact Source32 plane required')
guide=scale_nx(indices,4);labels=singleton_material_labels(guide)
owners=np.repeat(np.repeat(labels,4,0),4,1)
source_rgb=palette[guide].astype(float);output=np.zeros((512,512,3),float);base_output=np.zeros_like(output)
for component in range(5):
mask=(labels==component).astype(float)
if not np.any(mask):continue
weights=resize_float(gaussian(mask,1.0),(512,512))
numerator=resize_float(gaussian(source_rgb*mask[...,None],1.0),(512,512))
base=numerator/np.maximum(weights[...,None],1e-12)
donor=np.asarray(fields[component],float)
if donor.shape!=output.shape:raise ValueError('registered donor field size mismatch')
band=np.clip(donor-gaussian(donor,3.0),-16,16)*0.5
output[owners==component]=(base+band)[owners==component]
base_output[owners==component]=base[owners==component]
output=np.clip(np.rint(output),0,255).astype(np.uint8)
exact=np.repeat(np.repeat(palette[guide],4,0),4,1);protected=np.repeat(np.repeat((guide>=240)|(guide==102),4,0),4,1)
output[protected]=exact[protected]
# All logical owners that contain any Scale1..4 functional support are excluded from HD credit.
union=singleton_fidelity_union(indices);retained=np.zeros((32,32),bool)
for x,y in union:retained[y,x]=True
owner_retained=np.repeat(np.repeat(retained,16,0),16,1)
base8=np.clip(np.rint(base_output),0,255).astype(np.uint8)
changed=int(np.any(output!=base8,axis=2)[~owner_retained].sum())
if changed==0:raise ValueError('no surviving genuine generated RGB contribution; Original-only is not HD')
metrics={'original_detail_cells':union,'raw_Source_reserved_cells':int((indices>=240).sum()),'functional_support_union_cells':len(functional_support_union(indices)),'Source_fidelity_owner_union_cells':len(union),'Source102_raw_original_retention_cells':int((indices==102).sum()),'all_functional_SourceNx_RGB_exact':bool(np.array_equal(output[protected],exact[protected])),'nonfunctional_HDR_pixels':int((~owner_retained).sum()),'genuine_RGB_band_changed_nonfunctional_HDR_pixels':changed,'geometry_owner_sha256':hashlib.sha256(owners.tobytes()).hexdigest(),'Original_functional_HD_credit':0}
return output,owners,protected,metrics
FURTHER_COHORTS={('1059e',),('105a4','105a7')}
def further_material_labels(a):
a=np.asarray(a)
if a.ndim!=2 or a.dtype!=np.uint8:raise ValueError('indexed Source plane required')
labels=np.full(a.shape,-1,np.int8)
labels[a<24]=0 # lighter structural metal
labels[(a>=24)&(a<32)]=1 # black/char/slot geometry separated from pale structural color
labels[(a>=182)&(a<=207)]=2 # exact muted red earth family
labels[(a>=208)&(a<=239)]=3 # pale wedge/ordinary brown ground
labels[(a>=100)&(a<=111)]=4 # surviving ordinary green foliage
if np.any(labels<0):raise ValueError('unsupported actual further Source material, including all reserved labels')
return labels
def derive_further_tile(indices,palette,fields):
if set(fields)!=set(range(5)):raise ValueError('five genuine material donor fields required')
if indices.shape!=(32,32)or indices.dtype!=np.uint8:raise ValueError('exact Source32 plane required')
guide=scale_nx(indices,4);labels=further_material_labels(guide)
owners=np.repeat(np.repeat(labels,4,0),4,1)
source_rgb=palette[guide].astype(float);output=np.zeros((512,512,3),float);base_output=np.zeros_like(output)
for component in range(5):
mask=(labels==component).astype(float)
if not np.any(mask):continue
weights=resize_float(gaussian(mask,1.0),(512,512))
numerator=resize_float(gaussian(source_rgb*mask[...,None],1.0),(512,512))
base=numerator/np.maximum(weights[...,None],1e-12)
donor=np.asarray(fields[component],float)
if donor.shape!=output.shape:raise ValueError('registered donor field size mismatch')
band=np.clip(donor-gaussian(donor,3.0),-16,16)*0.5
if component in (0,1):band=np.repeat(np.mean(band,axis=2,keepdims=True),3,axis=2) # gray metal/dark slots remain achromatic; no red-char hue transfer into gap
output[owners==component]=(base+band)[owners==component]
base_output[owners==component]=base[owners==component]
output=np.clip(np.rint(output),0,255).astype(np.uint8)
exact=np.repeat(np.repeat(palette[guide],4,0),4,1);protected=np.repeat(np.repeat(guide>=240,4,0),4,1)
output[protected]=exact[protected]
# All logical owners that contain any Scale1..4 functional support are excluded from HD credit.
union=functional_support_union(indices);retained=np.zeros((32,32),bool)
for x,y in union:retained[y,x]=True
owner_retained=np.repeat(np.repeat(retained,16,0),16,1)
base8=np.clip(np.rint(base_output),0,255).astype(np.uint8)
changed=int(np.any(output!=base8,axis=2)[~owner_retained].sum())
if changed==0:raise ValueError('no surviving genuine generated RGB contribution; Original-only is not HD')
metrics={'original_detail_cells':union,'raw_Source_reserved_cells':int((indices>=240).sum()),'functional_support_union_cells':len(union),'all_functional_SourceNx_RGB_exact':bool(np.array_equal(output[protected],exact[protected])),'nonfunctional_HDR_pixels':int((~owner_retained).sum()),'genuine_RGB_band_changed_nonfunctional_HDR_pixels':changed,'geometry_owner_sha256':hashlib.sha256(owners.tobytes()).hexdigest(),'Original_functional_HD_credit':0}
return output,owners,protected,metrics
def main():
ap=argparse.ArgumentParser();ap.add_argument('--recipe',type=Path,required=True);ap.add_argument('--output',type=Path,required=True);args=ap.parse_args();recipe_bytes,recipe_pin=read_contained(args.recipe.parent,args.recipe.name,MAX_RECIPE_BYTES);recipe=json.loads(recipe_bytes);inputs=BufferedInputs(args.recipe.parent);out=args.output
_,tool_pin=read_contained(Path(__file__).parent,Path(__file__).name,1024*1024)
if out.exists():raise ValueError('new output directory required')
if recipe['method']!=METHOD:raise ValueError('unknown method')
pb,ppin=inputs.read(recipe['palette']);pal=palette_rgb(pb);aud=[]
sources=[]
if recipe['operation']=='further-first-tiles':
ids=tuple(x['asset']for x in recipe['sources'])
if ids not in FURTHER_COHORTS:raise ValueError('exact complete further selected cohort required')
fields={}
for key,binding in recipe['donors'].items():
payload,pin=inputs.read(binding);rgb=decode_png(payload);fields[int(key)]=donor_field(rgb,binding['box'],(512,512));aud.append(pin)
prepared=[]
for source in recipe['sources']:
b,pin=inputs.read(source);idx=decode_source32(b);result,owners,protected,one=derive_further_tile(idx,pal,fields);prepared.append((source['asset'],result,one));aud.append(pin)
out.mkdir(parents=True)
for aid,result,one in prepared:Image.fromarray(result).save(out/f'{aid}-derived.png')
metrics={'selected_ids':list(ids),'assets':[dict(asset=aid,**one)for aid,result,one in prepared],'global_SourceNx_nearest_fallback':False,'fine_band_sigma':3.0,'fine_band_clip':16,'fine_band_strength':0.5,'donor_repetition':False,'contract':'Actual selected3Source contain no reserved labels; unsupported/any reserved input rejected, never reclassified ordinary. Exact green/dark/structural component boundaries follow SourceNx.'}
elif recipe['operation']=='first-singleton-tiles':
ids=tuple(x['asset']for x in recipe['sources'])
if len(ids)!=1 or ids[0]not in SINGLETON_IDS:raise ValueError('exact complete selected singleton required')
fields={}
for key,binding in recipe['donors'].items():
payload,pin=inputs.read(binding);rgb=decode_png(payload);fields[int(key)]=donor_field(rgb,binding['box'],(512,512));aud.append(pin)
source=recipe['sources'][0];b,pin=inputs.read(source);idx=decode_source32(b);result,owners,protected,one=derive_singleton_tile(idx,pal,fields);aud.append(pin)
out.mkdir(parents=True);Image.fromarray(result).save(out/f'{ids[0]}-derived.png')
metrics={'selected_ids':list(ids),'assets':[dict(asset=ids[0],**one)],'global_SourceNx_nearest_fallback':False,'fine_band_sigma':3.0,'fine_band_clip':16,'fine_band_strength':0.5,'donor_repetition':False,'extra_Source_fidelity_retention':'Isolated ordinary102 green fixture SourceNx footprint, in addition to all>=240; all owner cells noHDcredit.'}
elif recipe['operation']=='next-pair-tiles':
ids=tuple(x['asset']for x in recipe['sources'])
if ids!=NEXT_PAIR_IDS:raise ValueError('exact complete next pair required')
fields={}
for key,binding in recipe['donors'].items():
payload,pin=inputs.read(binding);rgb=decode_png(payload);fields[int(key)]=donor_field(rgb,binding['box'],(512,512));aud.append(pin)
prepared=[]
for source in recipe['sources']:
b,pin=inputs.read(source);idx=decode_source32(b);result,owners,protected,one=derive_next_pair_tile(idx,pal,fields);prepared.append((source['asset'],result,one));aud.append(pin)
out.mkdir(parents=True)
for aid,result,one in prepared:Image.fromarray(result).save(out/f'{aid}-derived.png')
metrics={'selected_ids':list(ids),'assets':[dict(asset=aid,**one)for aid,result,one in prepared],'global_SourceNx_nearest_fallback':False,'fine_band_sigma':3.0,'fine_band_clip':16,'fine_band_strength':0.5,'donor_repetition':False}
elif recipe['operation']=='nine-tiles':
ids=tuple(x['asset']for x in recipe['sources'])
if ids not in COHORTS:raise ValueError('exact complete selected cohort required')
fields={}
for key,binding in recipe['donors'].items():
payload,pin=inputs.read(binding);rgb=decode_png(payload);fields[int(key)]=donor_field(rgb,binding['box'],(512,512),binding.get('texture_period'));aud.append(pin)
prepared=[]
for source in recipe['sources']:
b,pin=inputs.read(source);idx=decode_source32(b);result,owners,protected,one=derive_nine_tile(idx,pal,fields);prepared.append((source['asset'],result,one));aud.append(pin)
out.mkdir(parents=True)
for aid,result,one in prepared:Image.fromarray(result).save(out/f'{aid}-derived.png')
metrics={'selected_ids':list(ids),'assets':[dict(asset=aid,**one)for aid,result,one in prepared],'global_SourceNx_nearest_fallback':False}
elif recipe['operation']=='pair':
if [x['asset']for x in recipe['sources']]!=list(PAIR_IDS):raise ValueError('only complete selected pair supported')
for x in recipe['sources']:
b,pin=inputs.read(x);sources.append(decode_source32(b));aud.append(pin)
donors={}
for key,binding in recipe['donors'].items():
payload,pin=inputs.read(binding);rgb=decode_png(payload);donors[int(key)]=donor_field(rgb,binding['box'],(1024,512),binding.get('texture_period'));aud.append(pin)
band_audit={};result,owners,protected,guide=derive_pair(sources,pal,donors,band_audit);out.mkdir(parents=True)
Image.fromarray(result).save(out/'derived-pair1024x512.png')
for j,aid in enumerate(PAIR_IDS):Image.fromarray(result[:,j*512:(j+1)*512]).save(out/f'{aid}-derived.png')
metrics=dict(band_audit);metrics.update({'protected_native4_samples':int((guide>=240).sum()),'protected_HDraw_pixels':int(protected.sum()),'protected_source_Nx_RGBA_exact':bool(np.array_equal(result[protected],np.repeat(np.repeat(pal[guide],4,0),4,1)[protected])),'geometry_component_owner_sha256':hashlib.sha256(owners.tobytes()).hexdigest(),'retained_generated_texture_nonprotected_pixels':int(np.any(result!=np.repeat(np.repeat(pal[guide],4,0),4,1),axis=2)[~protected].sum())})
elif recipe['operation']=='T-landmark':
source=recipe['source'];assert source['asset']=='104fd';b,pin=inputs.read(source);idx=decode_source32(b);aud.append(pin)
# The measured Source has a full-width ochre top line at row9 and its lower arm at23.
if sum(80<=i<=95 for i in idx[9])!=32 or sum(80<=i<=95 for i in idx[23])!=19:raise ValueError('Source T topology changed')
payload,pin=inputs.read(recipe['donor']);rgb=decode_png(payload);x,y,w,h=recipe['donor']['box']
if min(x,y)<0 or min(w,h)<1 or x+w>rgb.shape[1]or y+h>rgb.shape[0]:raise ValueError('bad T donor crop')
result=warp_landmarks(rgb[y:y+h,x:x+w],**recipe['knots']);out.mkdir(parents=True);Image.fromarray(result).save(out/'104fd-derived.png');aud.append(pin);metrics={'source_top_yellow_row':9,'source_lower_yellow_row':23,'knots':recipe['knots'],'genuine_RGB_only_warp':True,'protected_Source_cells_to_declare_original_detail':[[int(x),int(y)]for y,x in zip(*np.where(idx>=240))]}
else:raise ValueError('unknown operation')
receipt={'implementation':tool_pin,'executed_dependency':_dependency_pin,'recipe_input':recipe_pin,'physical_authenticated_input_reads':inputs.physical_reads,'method':METHOD,'operation':recipe['operation'],'input_pins':aud,'palette':ppin,'recipe_sha256':hashlib.sha256(recipe_bytes).hexdigest(),'metrics':metrics,'output_is_derived_not_untouched':True,'functional_retention_no_HD_credit':'Original protected cells>=240 retain exact SourceNx RGB/labels. No global Original-nearest fallback is claimed as HD.','outputs':[{'file':p.name,'sha256':hashlib.sha256(p.read_bytes()).hexdigest()}for p in sorted(out.glob('*.png'))]};(out/'ACTUAL-DERIVATION-RECEIPT.json').write_text(json.dumps(receipt,indent=2)+'\n');print(json.dumps(receipt['metrics']))
if __name__=='__main__':main()
@@ -0,0 +1,60 @@
import unittest,tempfile,os,hashlib,io,struct,zlib
from pathlib import Path
from unittest.mock import patch
from PIL import Image
import numpy as np
import terrain_component_cleanup as m
class BufferedIOTests(unittest.TestCase):
def setUp(self):
self.temp=tempfile.TemporaryDirectory();self.root=Path(self.temp.name);(self.root/'inputs').mkdir();self.file=self.root/'inputs/a';self.file.write_bytes(b'bounded');self.binding={'path':'inputs/a','sha256':hashlib.sha256(b'bounded').hexdigest()}
def tearDown(self):self.temp.cleanup()
def test_absolute_and_dotdot_escape_rejected(self):
for rel in [str(self.file),'../outside','inputs/../inputs/a','./inputs/a','inputs//a','/etc/passwd']:
with self.assertRaises(ValueError):m.read_contained(self.root,rel)
def test_intermediate_and_final_symlink_rejected(self):
(self.root/'alias').symlink_to(self.root/'inputs',target_is_directory=True);(self.root/'inputs/link').symlink_to(self.file)
for rel in ['alias/a','inputs/link']:
with self.assertRaises((OSError,ValueError)):m.read_contained(self.root,rel)
def test_fifo_is_rejected_without_waiting_for_writer(self):
os.mkfifo(self.root/'inputs/fifo')
with self.assertRaises(ValueError):m.read_contained(self.root,'inputs/fifo')
def test_directory_is_not_regular_source(self):
with self.assertRaises(ValueError):m.read_contained(self.root,'inputs')
def test_stat_oversize_rejected_before_read(self):
with patch.object(m.os,'read',side_effect=AssertionError('must not read oversized source')):
with self.assertRaises(ValueError):m.read_contained(self.root,'inputs/a',3)
def test_bounded_eof_cannot_accept_extra_bytes(self):
with patch.object(m.os,'read',side_effect=[b'too-long',b'']):
with self.assertRaises(ValueError):m.read_contained(self.root,'inputs/a',7)
def test_cached_authenticated_source_never_reopens_path(self):
c=m.BufferedInputs(self.root);first,pin=c.read(self.binding);self.file.unlink()
with patch.object(m.os,'open',side_effect=AssertionError('cached path reopened')):
second,same=c.read(self.binding)
self.assertEqual(first,second);self.assertEqual(pin,same);self.assertEqual(c.physical_reads,1)
def test_bad_hash_and_changed_cached_expected_hash_rejected(self):
c=m.BufferedInputs(self.root)
with self.assertRaises(ValueError):c.read(dict(self.binding,sha256='0'*64))
c.read(self.binding)
with self.assertRaises(ValueError):c.read(dict(self.binding,sha256='1'*64))
def png(self):
f=io.BytesIO();Image.new('RGB',(8,8),(20,30,40)).save(f,format='PNG');return f.getvalue()
def test_png_decoded_from_bytesio_never_input_path(self):
raw=self.png();original=m.Image.open;seen=[]
def check(fp,*args,**kwargs):
self.assertIsInstance(fp,io.BytesIO);seen.append(True);return original(fp,*args,**kwargs)
with patch.object(m.Image,'open',side_effect=check),patch.object(Path,'read_bytes',side_effect=AssertionError('path reopen')):
result=m.decode_png(raw)
self.assertEqual(result.shape,(8,8,3));self.assertTrue(seen)
def test_png_declared_dimensions_bounded_before_convert(self):
raw=bytearray(self.png());raw[16:24]=struct.pack('>II',4097,1024);raw[29:33]=struct.pack('>I',zlib.crc32(raw[12:29]))
with patch.object(m.Image.Image,'convert',side_effect=AssertionError('oversized decode converted')):
with self.assertRaises(ValueError):m.decode_png(bytes(raw))
def test_non_png_encoded_oversize_and_nonopaque_rejected(self):
f=io.BytesIO();Image.new('RGBA',(2,2),(0,0,0,0)).save(f,format='PNG')
for raw in [f.getvalue(),b'x'*(m.MAX_INPUT_BYTES+1)]:
with self.assertRaises(ValueError):m.decode_png(raw)
f=io.BytesIO();Image.new('RGB',(2,2)).save(f,format='JPEG')
with self.assertRaises(ValueError):m.decode_png(f.getvalue())
def test_regular_bounded_payload_sha_and_size_truthful(self):
payload,pin=m.read_contained(self.root,'inputs/a');self.assertEqual(payload,b'bounded');self.assertEqual(pin['sha256'],self.binding['sha256']);self.assertEqual(pin['size'],7)
if __name__=='__main__':unittest.main()
@@ -0,0 +1,36 @@
import unittest,json,tempfile,hashlib
from pathlib import Path
from unittest.mock import patch
import numpy as np
import terrain_component_cleanup as m
class FurtherSelectorTests(unittest.TestCase):
def source(self):
a=np.full((32,32),225,np.uint8);a[:8,:]=15;a[8:16,:]=31;a[16:24,:]=197;a[24:,:]=105;return a
def palette(self):return np.repeat(np.arange(256,dtype=np.uint8)[:,None],3,axis=1)
def fields(self):
y,x=np.indices((512,512));return{i:np.stack([(x*19+y*11+i*7)%256,(x*13+y*17)%256,(x*3+y*7)%256],-1).astype(float)for i in range(5)}
def test_explicit_five_material_owners(self):
self.assertEqual(m.further_material_labels(np.array([[1,23,24,31,194,207,208,238,100,111]],np.uint8)).tolist(),[[0,0,1,1,2,2,3,3,4,4]])
def test_all_unsupported_or_reserved_are_rejected(self):
for v in [32,65,99,112,147,159,181,240,244,245,250,255]:
with self.assertRaises(ValueError):m.further_material_labels(np.array([[v]],np.uint8))
def test_actual_three_source_materials_and_no_functional_owners(self):
d=Path(__file__).parent/'inputs'
for aid in ['1059e','105a4','105a7']:
a=m.decode_source32((d/(aid+'.pic')).read_bytes());m.further_material_labels(a);self.assertEqual(m.functional_support_union(a),[])
a=m.decode_source32((d/'105a4.pic').read_bytes());self.assertEqual(int(((a>=100)&(a<=111)).sum()),105)
def test_exact_ownership_and_real_generated_band(self):
a=self.source();out,owners,prot,stats=m.derive_further_tile(a,self.palette(),self.fields());self.assertTrue(np.array_equal(owners,np.repeat(np.repeat(m.further_material_labels(m.scale_nx(a,4)),4,0),4,1)));self.assertFalse(np.any(prot));self.assertEqual(stats['original_detail_cells'],[]);self.assertGreater(stats['genuine_RGB_band_changed_nonfunctional_HDR_pixels'],0)
def test_green_donor_changes_only_green_not_slots_or_structure(self):
a=self.source();f=self.fields();out,owners,_,_=m.derive_further_tile(a,self.palette(),f);f[4]=255-f[4];other,_,_,_=m.derive_further_tile(a,self.palette(),f);self.assertTrue(np.array_equal(out[owners!=4],other[owners!=4]));self.assertTrue(np.any(out[owners==4]!=other[owners==4]))
def test_dark_slot_band_stays_achromatic(self):
out,owners,_,_=m.derive_further_tile(self.source(),self.palette(),self.fields());x=out[(owners==0)|(owners==1)];self.assertTrue(np.array_equal(x[:,0],x[:,1]));self.assertTrue(np.array_equal(x[:,1],x[:,2]))
def test_no_generated_detail_is_rejected_original_only(self):
with self.assertRaisesRegex(ValueError,'Original-only'):m.derive_further_tile(self.source(),self.palette(),{i:np.full((512,512,3),80.,float)for i in range(5)})
def test_incomplete_or_foreign_cohort_rejected_before_output(self):
for ids in [['105a4'],['105a7','105a4'],['1059f']]:
with tempfile.TemporaryDirectory()as d:
d=Path(d);p=bytes(768);(d/'pal').write_bytes(p);rec={'method':m.METHOD,'operation':'further-first-tiles','palette':{'path':'pal','sha256':hashlib.sha256(p).hexdigest()},'sources':[{'asset':x}for x in ids]};(d/'recipe.json').write_text(json.dumps(rec))
with patch('sys.argv',['tool','--recipe',str(d/'recipe.json'),'--output',str(d/'none')]),self.assertRaisesRegex(ValueError,'complete further'):m.main()
self.assertFalse((d/'none').exists())
if __name__=='__main__':unittest.main()
@@ -0,0 +1,38 @@
import unittest,json,tempfile,hashlib
from pathlib import Path
from unittest.mock import patch
import numpy as np
import terrain_component_cleanup as m
class NextPairTests(unittest.TestCase):
def source(self):
a=np.full((32,32),225,np.uint8);a[:,:10]=154;a[:10,10:20]=15;a[10:20,10:20]=82;a[20:,10:20]=43
a[3,3]=a[3,4]=a[4,3]=243;return a
def palette(self):return np.stack([np.arange(256,dtype=np.uint8),np.arange(256,dtype=np.uint8)[::-1],np.arange(256,dtype=np.uint8)],-1)
def fields(self):
y,x=np.indices((512,512));return{i:np.stack([(x*19+y*11+i*7)%256,(x*13+y*17)%256,(x*3+y*7)%256],-1).astype(float)for i in range(5)}
def test_actual_materials_and_all_reserved_classes(self):
a=np.array([[65,191,219,31,154,243,255,34,38,39,42,43,44]],np.uint8);self.assertEqual(m.next_pair_material_labels(a).tolist(),[[3,2,2,1,0,0,5,4,4,4,4,4,4]])
def test_unknown_source_red_or_other_material_rejected(self):
for v in [32,35,37,40,41,45,64,66,147,160,181]:
with self.assertRaises(ValueError):m.next_pair_material_labels(np.array([[v]],np.uint8))
def test_exact_geometry_protected_and_positive_real_band(self):
a=self.source();p=self.palette();out,owners,prot,stats=m.derive_next_pair_tile(a,p,self.fields());guide=m.scale_nx(a,4)
self.assertTrue(np.array_equal(owners,np.repeat(np.repeat(m.next_pair_material_labels(guide),4,0),4,1)));self.assertTrue(np.array_equal(out[prot],np.repeat(np.repeat(p[guide],4,0),4,1)[prot]));self.assertGreater(stats['genuine_RGB_band_changed_nonfunctional_HDR_pixels'],0);self.assertEqual(stats['Original_functional_HD_credit'],0)
def test_red_donor_change_cannot_move_contacts_or_touch_other_components(self):
f=self.fields();a=self.source();out,owners,_,_=m.derive_next_pair_tile(a,self.palette(),f);f[4]=255-f[4];changed,owners2,_,_=m.derive_next_pair_tile(a,self.palette(),f);self.assertTrue(np.array_equal(owners,owners2));self.assertTrue(np.array_equal(out[owners!=4],changed[owners!=4]));self.assertTrue(np.any(out[owners==4]!=changed[owners==4]))
def test_constant_fields_rejected_as_original_only(self):
with self.assertRaisesRegex(ValueError,'Original-only'):m.derive_next_pair_tile(self.source(),self.palette(),{i:np.full((512,512,3),60.,float)for i in range(5)})
def test_missing_or_extra_field_rejected(self):
for fs in [{i:np.zeros((512,512,3))for i in range(4)},{i:np.zeros((512,512,3))for i in range(6)}]:
with self.assertRaises(ValueError):m.derive_next_pair_tile(self.source(),self.palette(),fs)
def test_actual_originals_and_functional_union(self):
d=Path(__file__).parent/'inputs'
for aid in m.NEXT_PAIR_IDS:
a=m.decode_source32((d/(aid+'.pic')).read_bytes());m.next_pair_material_labels(a)
self.assertEqual(len(m.functional_support_union(a)),{'10536':1,'1053e':0}[aid])
def test_wrong_order_rejected_without_output(self):
with tempfile.TemporaryDirectory()as d:
d=Path(d);p=bytes(768);(d/'pal').write_bytes(p);rec={'method':m.METHOD,'operation':'next-pair-tiles','palette':{'path':'pal','sha256':hashlib.sha256(p).hexdigest()},'sources':[{'asset':'1053e'},{'asset':'10536'}]};(d/'recipe.json').write_text(json.dumps(rec))
with patch('sys.argv',['tool','--recipe',str(d/'recipe.json'),'--output',str(d/'none')]),self.assertRaisesRegex(ValueError,'complete next pair'):m.main()
self.assertFalse((d/'none').exists())
if __name__=='__main__':unittest.main()
@@ -0,0 +1,36 @@
import unittest,json,tempfile,hashlib
from pathlib import Path
from unittest.mock import patch
import numpy as np
import terrain_component_cleanup as m
class NineSelectorTests(unittest.TestCase):
def source(self):
a=np.full((32,32),152,np.uint8);a[:12,:12]=197;a[:12,12:]=226;a[12:24,12:]=82;a[24:,12:]=18
for i,value in enumerate([240,244,245,249,250,255]):a[2+i,2]=value
return a
def palette(self):return np.stack([np.arange(256,dtype=np.uint8),np.arange(256,dtype=np.uint8)[::-1],np.arange(256,dtype=np.uint8)],-1)
def fields(self):
y,x=np.indices((512,512));return {i:np.stack([(x*19+y*11+i*7)%256,(x*13+y*17)%256,(x*3+y*7)%256],-1).astype(float)for i in range(5)}
def test_explicit_actual_148_191_and_all_protected_classes(self):
a=np.array([[148,191,173,82,240,244,245,249,250,255]],np.uint8);self.assertEqual(m.nine_material_labels(a).tolist(),[[0,2,1,4,0,0,5,5,5,5]])
def test_unknown_ordinary_material_rejected(self):
for index in [32,64,96,147,160,181]:
with self.assertRaises(ValueError):m.nine_material_labels(np.array([[index]],np.uint8))
def test_full_functional_union_covers_scalenx_spill(self):
a=np.full((32,32),152,np.uint8);a[8,8]=a[8,9]=a[9,8]=244;cells=m.functional_support_union(a);self.assertIn([9,9],cells);self.assertEqual(len(cells),4)
def test_actual_nine_source_union_counts_match_independent_source_plan(self):
root=Path(__file__).parent/'inputs';expected={'10502':6,'10504':31,'10506':6,'10508':9,'10509':0,'1050a':11,'1050b':34,'1050c':36,'1050e':33}
for aid,count in expected.items():self.assertEqual(len(m.functional_support_union(m.decode_source32((root/(aid+'.pic')).read_bytes()))),count,aid)
def test_registered_geometry_protection_and_positive_genuine_band(self):
a=self.source();pal=self.palette();out,owners,protected,stats=m.derive_nine_tile(a,pal,self.fields());guide=m.scale_nx(a,4);self.assertTrue(np.array_equal(owners,np.repeat(np.repeat(m.nine_material_labels(guide),4,0),4,1)));exact=np.repeat(np.repeat(pal[guide],4,0),4,1);self.assertTrue(np.array_equal(out[protected],exact[protected]));self.assertGreater(stats['genuine_RGB_band_changed_nonfunctional_HDR_pixels'],0);self.assertEqual(stats['Original_functional_HD_credit'],0)
def test_zero_generated_band_rejected_not_named_HD(self):
with self.assertRaisesRegex(ValueError,'Original-only'):m.derive_nine_tile(self.source(),self.palette(),{i:np.full((512,512,3),90.,float)for i in range(5)})
def test_field_selector_missing_component_rejected(self):
fields=self.fields();del fields[4]
with self.assertRaises(ValueError):m.derive_nine_tile(self.source(),self.palette(),fields)
def test_foreign_or_incomplete_source_cohort_rejected_before_art(self):
with tempfile.TemporaryDirectory()as d:
root=Path(d);pb=bytes(768);(root/'pal').write_bytes(pb);recipe={'method':m.METHOD,'operation':'nine-tiles','palette':{'path':'pal','sha256':hashlib.sha256(pb).hexdigest()},'sources':[{'asset':'10501'}]};(root/'recipe.json').write_text(json.dumps(recipe));argv=['tool','--recipe',str(root/'recipe.json'),'--output',str(root/'no-output')]
with patch('sys.argv',argv),self.assertRaisesRegex(ValueError,'complete selected cohort'):m.main()
self.assertFalse((root/'no-output').exists())
if __name__=='__main__':unittest.main()
@@ -0,0 +1,38 @@
import unittest,json,tempfile,hashlib
from pathlib import Path
from unittest.mock import patch
import numpy as np
import terrain_component_cleanup as m
class SingletonSelectorTests(unittest.TestCase):
def source(self):
a=np.full((32,32),225,np.uint8);a[:8,:]=154;a[8:16,:]=15;a[16:24,:]=82;a[24:,:16]=43;a[1,1]=245;a[1,2]=250;a[10,10]=102;return a
def palette(self):return np.stack([np.arange(256,dtype=np.uint8),np.arange(256,dtype=np.uint8)[::-1],np.arange(256,dtype=np.uint8)],-1)
def fields(self):
y,x=np.indices((512,512));return{i:np.stack([(x*19+y*11+i*7)%256,(x*13+y*17)%256,(x*3+y*7)%256],-1).astype(float)for i in range(5)}
def test_explicit_green_orange_red_and_protected(self):
self.assertEqual(m.singleton_material_labels(np.array([[102,69,70,73,75,82,38,40,41,43,245,250,255]],np.uint8)).tolist(),[[5,3,3,3,3,3,4,4,4,4,5,5,5]])
def test_unknown_classes_rejected(self):
for v in [32,34,37,44,65,68,71,72,74,76,101,103,147,160,181]:
with self.assertRaises(ValueError):m.singleton_material_labels(np.array([[v]],np.uint8))
def test_actual_original_support_and_isolated_fixture_contract(self):
d=Path(__file__).parent/'inputs'
for aid,count,rawfun in [('1054f',13,12),('10561',1,1)]:
a=m.decode_source32((d/(aid+'.pic')).read_bytes());m.singleton_material_labels(a);self.assertEqual(len(m.singleton_fidelity_union(a)),count);self.assertEqual(len(m.functional_support_union(a)),rawfun)
a=m.decode_source32((d/'1054f.pic').read_bytes());self.assertEqual(int(a[4,1]),102);self.assertIn([1,4],m.singleton_fidelity_union(a))
def test_green_and_fire_exact_with_positive_generated_fine_band(self):
a=self.source();p=self.palette();out,own,protected,stats=m.derive_singleton_tile(a,p,self.fields());guide=m.scale_nx(a,4);exact=np.repeat(np.repeat(p[guide],4,0),4,1);self.assertTrue(np.array_equal(out[protected],exact[protected]));self.assertEqual(stats['Original_functional_HD_credit'],0);self.assertGreater(stats['genuine_RGB_band_changed_nonfunctional_HDR_pixels'],0);self.assertEqual(stats['Source102_raw_original_retention_cells'],1);self.assertGreater(stats['Source_fidelity_owner_union_cells'],stats['functional_support_union_cells'])
def test_gray_donor_changes_only_gray_owners_not_earth_water_or_fire(self):
a=self.source();f=self.fields();p=self.palette();out,owners,protected,_=m.derive_singleton_tile(a,p,f);f[1]=255-f[1];changed,_,_,_=m.derive_singleton_tile(a,p,f);self.assertTrue(np.array_equal(out[owners!=1],changed[owners!=1]));self.assertTrue(np.any(out[owners==1]!=changed[owners==1]));self.assertTrue(np.array_equal(out[protected],changed[protected]))
def test_no_generated_band_is_original_only_rejected(self):
with self.assertRaisesRegex(ValueError,'Original-only'):m.derive_singleton_tile(self.source(),self.palette(),{i:np.full((512,512,3),90.,float)for i in range(5)})
def test_two_singletons_or_wrong_id_rejected_before_output(self):
for ids in [['1054f','10561'],['1054e']]:
with tempfile.TemporaryDirectory()as d:
d=Path(d);p=bytes(768);(d/'pal').write_bytes(p);rec={'method':m.METHOD,'operation':'first-singleton-tiles','palette':{'path':'pal','sha256':hashlib.sha256(p).hexdigest()},'sources':[{'asset':x}for x in ids]};(d/'recipe.json').write_text(json.dumps(rec))
with patch('sys.argv',['tool','--recipe',str(d/'recipe.json'),'--output',str(d/'none')]),self.assertRaisesRegex(ValueError,'selected singleton'):m.main()
self.assertFalse((d/'none').exists())
def test_source_red_gap_mask_is_exact_no_implicit_red_rectangle(self):
d=Path(__file__).parent/'inputs';a=m.decode_source32((d/'10561.pic').read_bytes());labels=m.singleton_material_labels(a);self.assertTrue(np.array_equal(labels==4,np.isin(a,[38,39,40,41,42,43])))
for x,y in [(25,0),(27,0),(30,0)]:self.assertNotEqual(int(labels[y,x]),4)
for x,y in [(27,6),(30,10)]:self.assertEqual(int(labels[y,x]),4)
if __name__=='__main__':unittest.main()
@@ -0,0 +1,42 @@
import unittest,struct
import numpy as np
import terrain_component_cleanup as m
class GeometryTests(unittest.TestCase):
def palette(self):
p=np.tile(np.arange(256,dtype=np.uint8)[:,None],(1,3));p[:,1]=(p[:,1].astype(int)*3%256).astype(np.uint8);return p
def sources(self):
a=np.full((32,32),152,np.uint8);a[:12,:]=197;a[:,13:18]=18;a[:12,18:]=226;a[12:16,18:]=226;a[17:23,18:]=226;a[24:,18:]=226;a[20,1]=242;return [a,a[:,::-1].copy()]
def fields(self):
y,x=np.indices((512,1024));return {i:np.stack([(x*19+y*11+i*7)%256,(x*13+y*17)%256,(x*3+y*7)%256],axis=-1).astype(float)for i in range(5)}
def test_source_decode_includes_honest_protected_indices(self):
a=self.sources()[0];data=struct.pack('<5i',1,1,0,32,32)+a.tobytes();self.assertTrue(np.array_equal(m.decode_source32(data),a));self.assertEqual(m.decode_source32(data)[20,1],242)
def test_bad_format_and_truncated_source_rejected(self):
for b in [b'',struct.pack('<5i',0,1,0,32,32)+bytes(1024),struct.pack('<5i',1,1,0,32,32)+bytes(1023)]:
with self.assertRaises(ValueError):m.decode_source32(b)
def test_nonwater_protected_class_not_reclassified_as_ordinary(self):
a=self.sources()[0];a[2,2]=249
with self.assertRaises(ValueError):m.material_labels(a,12)
def test_material_masks_and_approach_are_exact(self):
a=self.sources()[0];labels=m.material_labels(a,12);self.assertEqual(labels[20,1],0);self.assertEqual(labels[5,13],1);self.assertEqual(labels[5,2],2);self.assertEqual(labels[10,22],4);self.assertEqual(labels[20,22],3);self.assertEqual(labels[16,22],0);self.assertEqual(labels[23,22],0)
def test_registered_pair_geometry_and_protected_samples(self):
sources=self.sources();pal=self.palette();out,owners,protected,guide=m.derive_pair(sources,pal,self.fields());expected=m.material_labels(guide,48);self.assertTrue(np.array_equal(owners,np.repeat(np.repeat(expected,4,0),4,1)));self.assertTrue(np.array_equal(out[protected],np.repeat(np.repeat(pal[guide],4,0),4,1)[protected]));self.assertEqual(out.shape,(512,1024,3));self.assertTrue(protected.any());self.assertTrue(np.any(out[~protected]!=np.repeat(np.repeat(pal[guide],4,0),4,1)[~protected]))
def test_different_genuine_texture_changes_only_its_component(self):
s=self.sources();p=self.palette();f=self.fields();out,owners,_,_=m.derive_pair(s,p,f);g={k:v.copy()for k,v in f.items()};g[3]=255-g[3];new,_,_,_=m.derive_pair(s,p,g);self.assertTrue(np.array_equal(new[owners!=3],out[owners!=3]));self.assertTrue(np.any(new[owners==3]!=out[owners==3]))
def test_missing_component_rejected(self):
f=self.fields();del f[3]
with self.assertRaises(ValueError):m.derive_pair(self.sources(),self.palette(),f)
def test_both_frames_required(self):
with self.assertRaises(ValueError):m.derive_pair(self.sources()[:1],self.palette(),self.fields())
def test_crop_cannot_escape_genuine_image(self):
a=np.zeros((8,8,3),np.uint8)
for box in [(-1,0,3,3),(0,0,9,8),(0,0,0,2)]:
with self.assertRaises(ValueError):m.donor_field(a,box,(8,8))
def test_identity_mesh_preserves_every_rgb_pixel(self):
a=np.arange(16*16*3,dtype=np.uint8).reshape(16,16,3);knots=[0,.5,1];self.assertTrue(np.array_equal(m.warp_landmarks(a,knots,knots,knots,knots),a))
def test_landmark_rows_are_moved_without_inventing_texture(self):
a=np.zeros((32,32,3),np.uint8);a[8:10]=[100,150,200];b=m.warp_landmarks(a,[0,1],[0,.5,1],[0,1],[0,.25,1]);self.assertGreater(b[16,:,1].max(),100);self.assertEqual(b.shape,a.shape)
def test_reversed_missing_nan_mesh_knots_rejected(self):
a=np.zeros((8,8,3),np.uint8)
for k in [[0,.7,.6,1],[.1,1],[0,float('nan'),1],[0,0,1]]:
with self.assertRaises(ValueError):m.warp_landmarks(a,[0,1],k,[0,1],k)
if __name__=='__main__':unittest.main()