!**************************************************************** !* * !* IFFDISP: Program displays JHB-modded IFF files * !* * !* Version 1.17 30 Nov 1987 * !* * !**************************************************************** %include "inc:util.imp" {%include "src:util.imp"} {FS-D} %include "iff:iffinc.imp" {%include "demo:iff:iffinc.imp} {FS-D} !Takes a run-length encoded IFF' file, expands it, rearranges it and displays it. !v1.10 allows non-square zooming !v1.17 displays 16-bit and real images but not 32-bit integers !! mouse functions("","Box","Keybd") !! mouse functions("Restart", "Corner", "Restart") !! mouse functions("Restart", "Write", "Zoom") !! mouse functions("Restart", "+ Zoom *", "- Zoom *") %begin %include "level1:graphinc.imp" %constinteger maxwins=5 %integerarray xbase, ybase, iwid, iht, xsize, ysize(0:maxwins-1) %string (255) param, infile, outfile %integer xsam, ysam, imageno, max %routine Set Up Offset (0,0) enable(16_FF) Colour (White) Set Terminal Mode (Nopage) %end %routine getfile(%string (255) %name file, %string (255) ext) !Hook prompt("file:"); readline(file) %until file#"" %end %routine clanprint(%record (iffhdr fm) %name iffhdr, %integer a, %integer x0,y0,x1,y1, %string (255) file) %integer scaleX, scaleY, wid, ht %constinteger MAXD=16 %constinteger MAXDSQR=256 %bytearray dither(0:MAXDSQR-1) %constintegerarray random(0:15) = %c 0, 8, 2,10, 12, 4,14, 6, 3,11, 1, 9, 15, 7,13, 5 ! designed to clump dots %constintegerarray dithfont(0:15) = %c 0, 1, 4, 9, 2, 3, 5,10, 6, 7, 8,11, 12,13,14,15 ! DITHER MATRIX PRODUCTION %routine make dith; ! writen for clarity rather than speed %integer r,c,row,col %for r=0,1,3 %cycle; %for c=0,1,3 %cycle %for row=0,1,3 %cycle; %for col=0,1,3 %cycle dither(4*(c+r*MAXD)+col+row*MAXD) = 16*dithfont(row*4+col)+random(r*4+c) %repeat; %repeat %repeat; %repeat %end %routine send header(%integer x,y) printline("$g1") printline("X(".itos(x,-1).""")") printline("Y(".itos(y,-1).""")") printline("B(".itos(wid*scaleX,-1).",".itos(ht*scaleY,-1).")") %end %routine send trailer newline; ! end of last line printline("$e*") %end %routine dot line(%integer dp, %bytearrayname bufp) %integer d1p, d count, b count, bptr, dot pattern,bufsize bufsize = wid * scaleX d1p=dp; d count=0 dot pattern=0; bcount=0 %for bptr=0,1,bufsize-1 %cycle dot pattern=dot pattern<<1 dot pattern = dot pattern ! 1 %if bufp(bptr) >{=} dither(dp) & 16_FF %if dcount2048//wid; scaleY=2048//ht %if scaleY>2048//ht open output(2, file); selectoutput(2) send header(0,0) d count=0; dp=0 %for j=y0,1,y1 %cycle getbuf(ad, buf); ad=ad+iffhdr_wid %for s=0,1,scaleY-1 %cycle dot line(dp,buf) %if d count0 %and yl>0 %start ix=0 %for i=0, yfactor, yl-yfactor %cycle %for j=0, xfactor, xl-xfactor %cycle b(ix) = a(i*iffh_wid+j); ix=ix+1 %repeat %repeat %finish col fill(xoff,yoff, xoff+xn-1, yoff+yn-1, b(0)) %end %end %routine zoom(%record (iffhdr fm) %name iffh, %c %bytearrayname a(0:*), %integer xfactor, yfactor, xoff, yoff) !! %integer i, j, k, l, ix, ifw, iw, fac, facfac !! !! %begin !! %bytearray b(0:xfactor*yfactor*iffh_ht*iffh_wid-1) !! !! fac = xfactor * iffh_wid !! facfac = fac * yfactor !! iw=0; ifw=facfac !! %for i=iffh_ht-1, -1, 0 %cycle !! ix = ifw !! %for j=yfactor-1, -1, 0 %cycle !! %for k=iffh_wid-1,-1,0 %cycle !! ix=ix-xfactor !! %for l=xfactor-1, -1, 0 %cycle !! b(ix+l) = a(iw+k) !! %repeat !! %repeat !! %repeat !! iw=iw + iffh_wid; ifw=ifw+facfac !! %repeat !! col fill(xoff,yoff, xoff+iffh_wid*xfactor-1, yoff+iffh_ht*yfactor-1, b(0)) !! %end %integer i, j, k, l, ix, ifw, iw, fac, facfac %begin %label l1, l2, l3, l4, l5, l7 %bytearray b(0:xfactor*yfactor*iffh_ht*iffh_wid-1) fac = xfactor * iffh_wid facfac = fac * yfactor ! Slightly bizarre code - took IMP -code and hacked grossest bits. *CLR.L iw *MOVE.L D0,ifw *MOVE.L 8(A0),i L1: *MOVE.L i,D0 *BEQ L2 *SUBQ.L #1,i *MOVE.L ifw,d3 *MOVE.L yfactor,j L3: *MOVE.L j,D0 *BEQ L4 *SUBQ.L #1,j *MOVEA.L iffh,A0 *MOVE.L 12(A0),d2 ; *subq.l #1,d2 ;!d2 = k = iffhdr_wid-1 L5: *move.l xfactor,d0 *sub.l d0,d3 ;!ix = ix - xfactor *MOVEA.L b,A1 *adda.l d3,a1 *adda.l d0,a1 ;!a1 points at b(ix+xfactor) *MOVEA.L a,A0 *MOVE.L iw,d1 *ADD.L d2,d1 ;!d2 = k *adda.l d1,a0 ;!a0 points at a(iw+k) L7: *MOVE.B (A0),-(A1) ;!copy across *dbra d0, l7 *dbra d2, l5 *Bra l3 L4: *movea.L iffh,A0 *move.l 12(A0),D1 *add.l D1,iw *move.l facfac,D2 *add.l D2,ifw *BRA L1 L2: col fill(xoff,yoff, xoff+iffh_wid*xfactor-1, yoff+iffh_ht*yfactor-1, b(0)) %end %end %constinteger iff op stream = 1 %routine select region(%record (iffhdr fm) %name iffhdr, %integer xoff,yoff,aa) %integer i,j,k,p,x0,y0,x1,y1,x2,y2,q,x,y,ox,oy,z,mb,tx,ty,rc,rcx,rcy,wid,ht %record (iffhdr fm) iffout, tempiffh %bytearrayname a(0:*) %bytearray tempa(0:256*256) %routine swap(%integername a, b) %integer t t=a; a=b; b=t %end %routine dohline(%integer xb, xt, y) %integer i,j,m,n %bytearray b(0:wid-1) xb=xoff %if xbtx; y=ty %if y>ty swap(xb, xt) %if xttx; yt=ty %if yt>ty swap(yb, yt) %if yttx; y=ty %if y>ty swap(xb, xt) %if xttx; yt=ty %if yt>ty swap(yb, yt) %if yttx x1=tx ox=x-wid %if ox<-2048 %then ox=ox+4096 %finish %if y1ty y1=ty oy=y-ht %if oy<-2048 %then oy=oy+4096 %finish !Now xoff<=x1<=tx and yoff<=y1<=ty %end wid=iffhdr_wid; ht=iffhdr_ht a == array(aa) tx = xoff+wid-1; ty = yoff + ht-1 try again: clear col fill(xoff, yoff, tx, ty,a(0)) %cycle; %repeatuntil mouse buttons=0 oldx=-1; oldy=-1; oldz=-1 mouse functions("","Box","Keybd") x2=xoff; y2=yoff ox=mouse x; oy=mouse y %cycle ;! ----- Loop, displaying [X,Y,Z] coords till user presses button ----- Get x1 y1 !Write new cursor dohline(x1-5,x1+5,y1) dovline(x1 ,y1-5,y1+5) %if x2#x1 %or y2#y1 %start !Delete old cursor unhline(x2-5,x2+5,y2) unvline(x2 ,y2-5,y2+5) x2=x1; y2=y1 %finish monitor mb = mouse buttons %repeatuntil mb#0 !----- User has hit a button ----- !----- all 3 = quit %return %if mb=7 !----- Middle = "anchor corner and generate a box" ----- %if mb=mouse middle %start ! delete cursor unhline(x2-5,x2+5,y2) unvline(x2 ,y2-5,y2+5) !Wait for him to get his fingers off the buttons %cycle; %repeatuntil mouse buttons=0 mouse functions("Restart", "Corner", "Restart") x0=x1; y0=y1 x2=x0; y2=y0 %cycle ;!----- Now loop with a rubber-banded box till user hits a button ----- Get x1 y1 !! x=mouse x; y=mouse y !! x1=x-ox+xoff; y1=y-oy+yoff !! !! %if x1tx !! x1=tx !! ox=x-wid !! %if ox<-2048 %then ox=ox+4096 !! %finish !! !! %if y1ty !! y1=ty !! oy=y-ht !! %if oy<-2048 %then oy=oy+4096 !! %finish drawbox(x0,y0,x1,y1) %if x2#x1 %or y2#y1 %start undrawbox(x0,y0,x2,y2) x2=x1; y2=y1 %finish monitor mb = mouse buttons %repeatuntil mb#0 %and x0#x1 %and y0#y1 undrawbox(x0,y0,x1,y1) %and -> try again %if mb=mouse right %or mb=mouse left %return %if mb=7 %elseif mb=mouse right ;!Get coords from the keyboard q=0 %cycle prompt("Xl:"); read(x0); x0=x0+xoff prompt("yl:"); read(y0); y0=y0+yoff prompt("Xr:"); read(x1); x1=x1+xoff prompt("Yt:"); read(y1); y1=y1+yoff undrawbox(x,y,x2,y2) %if q#0 x=x0; y=y0; x2=x1; y2=y1 drawbox(x0, y0, x1, y1) prompt("OK?") %cycle; readsymbol(q); q=q&16_5F; %repeatuntil q='Y' %or q='N' %repeatuntil q='Y' %finish %cycle; %repeatuntil mouse buttons=0 undrawbox(x0,y0,x2,y2) x0=x0-xoff; x1=x1-xoff; y0=y0-yoff; y1=y1-yoff swap(y0, y1) %if y0>y1; swap(x0, x1) %if x0>x1 printstring("Coords (pixels) are: [") write(x0,-1); printsymbol(','); write(y0,-1) printstring("] [") write(x1,-1); printsymbol(','); write(y1,-1) printstring("]"); newline %cycle %cycle; %repeatuntil mousebuttons=0 mouse functions("Restart", "Zoom", "Write") %cycle; mb=mouse buttons; %repeatuntil mb#0 %if mb=7 %start %return %elseif mb=mouse middle tempiffh = 0 tempiffh_ht = y1-y0+1; tempiffh_wid = x1-x0+1 tempiffh_ht=256 %if tempiffh_ht>256; tempiffh_wid=256 %if tempiffh_wid>256 k=0 %for i=0,1,tempiffh_ht-1 %cycle p=(y0+i)*iffhdr_wid+x0 %for j=0,1,tempiffh_wid-1 %cycle tempa(k) = a(p); k=k+1; p=p+1 %repeat %repeat !! prompt("Zoom factor:"); read(rc) mouse functions("Display","+ Zoom *","- Zoom *") colour(area col); fill(menul, 400, menul+64, 447) colour(text col); textat(menul,432); showstring("Zoom *") rcx=1; rcy=1 %cycle colour(area col); fill(menul+48, 432, menul+80, 447) colour(text col); textat(menul+48, 432); show i(rcx, 1) show i(rcy, 1) %cycle; mb=mouse buttons; %repeatuntil mb=0 %cycle; mb=mouse buttons; %repeatuntil mb#0 %if mb=mouse left %start %exit %elseif mb=mouse middle ! mouse right %and rcx=3 rcx=4; rcy=3 %elseif mb=mouse middle rcx=rcx+1; rcy=rcy+1 %elseif mb=mouse right rcx=rcx-1 %if rcx>1; rcy=rcy-1 %if rcy>1 %elseif mb=7 %return %finish %repeat textat(menul, 400); showstring("Zooming") zoom(tempiffh, tempa, rcx, rcy, 0, 0) %elseif mb=mouse right %cycle; %repeatuntil mousebuttons=0 mouse functions("Restart", "IFF", "Lay 2.0") %cycle; mb=mousebuttons; %repeatuntil mb#0 %if mb=mouse left %start %return %elseif mb=mouse middle getfile(outfile,"iff") %if outfile="" rc = iff open file(outfile, iffout, iff write) iffout_ht = y1-y0+1; iffout_wid=x1-x0+1 iffout_mapaddr = iffhdr_mapaddr; iffout_maplen = iffhdr_maplen rc = iff write header(iffout) selectoutput(iffout_context_filptr) %for y=y0, 1, y1 %cycle q = aa + y*wid + x0 %for x=x0, 1, x1 %cycle printsymbol(byteinteger(q)); q=q+1 %repeat %repeat selectoutput(0) iff close file(iffout) %elseif mb=mouse right getfile(outfile,"dot") %if outfile="" clanprint(iffhdr, aa, x0,y0, x1,y1, outfile) %finish %elseif mb=mouse left %exit %finish %repeat -> try again %end %routine moveit(%record (iffhdr fm) iffhdr, %integer a,low,high, seq) %string (255) s1, s2, factor %integer xo, yo, c, xfactor, yfactor, i, j, xoff, yoff, base, mb %integer max xfactor, maxyfactor, xshrink, yshrink printline("Cursor keys pan image, zooms, exits, Mouse edits") xo=0; yo=0; xoff=0; yoff=0 %cycle %cycle; %repeatuntil mouse buttons=0 %and testsymbol<0 offset(xo, yo) %cycle;c=testsymbol;mb=mouse buttons;%repeatuntil c=27 %or c=10 %or mb#0 %exit %if mb#0 %return %if c=10 !V200 and Wyse use same cursor key ASCII values bar a '[' %cycle %cycle; c=testsymbol; %repeatuntil c>0 %repeatuntil c # '[' %if c=67 %start xo=xo-16 %elseif c=65 yo=yo-1 %elseif c=68 xo=xo+16 %elseif c=66 yo=yo+1 %elseif c=72 ;!Home prompt("Zoom factor(s):"); readline(factor) s1=factor %and s2=s1 %unless factor -> s1.("/").s2 xfactor = stoi(s1); yfactor=stoi(s2) %if xfactor>=0 %then xshrink=0 %else xfactor=-xfactor %and xshrink=1 %if yfactor>=0 %then yshrink=0 %else yfactor=-yfactor %and yshrink=1 %if xfactor<1 %or yfactor<1 %then clear %elsestart base=0 %for i=low, 1, high %cycle max xfactor = xsize(i)//iffhdr_wid; max yfactor = ysize(i)//iffhdr_ht %if xfactor<=max xfactor %then max xfactor = xfactor %if yfactor<=max yfactor %then max yfactor = yfactor printstring("Image "); write(i, 2) printstring(": Zoom factor = "); write(max xfactor, -1) %if max yfactor#max xfactor %then printstring("/".itos(max yfactor,-1)) newline %if xshrink=0 %and yshrink=0 %start xoff=xbase(i)+(xsize(i)-iffhdr_wid*max xfactor)>>1 yoff=ybase(i)+(ysize(i)-iffhdr_ht*max yfactor)>>1 zoom(iffhdr, array(a+base), max xfactor, max yfactor, xoff, yoff) %elseif xshrink#0 %and yshrink#0 xoff=xbase(i)+(xsize(i)-iffhdr_wid//xfactor)>>1 yoff=ybase(i)+(ysize(i)-iffhdr_ht//yfactor)>>1 shrink(iffhdr, array(a+base), xfactor, yfactor, xoff, yoff) %finish base=base+iffhdr_wid*iffhdr_ht %repeat %finish %while testsymbol>=0 %cycle; %repeat %finish %repeat %cycle; %repeatuntil mouse buttons=0 select region(iffhdr,iffhdr_xoff,iffhdr_yoff, a) %end %predicate graphics present %on 0 %start %false %finish plot(0,0) %true %end %routine iff real to 8(%record (iffhdr fm) %name iffh, %integer from, to) %integer i, p, q %real v, vmin, vmax, s %recordformat rf(%real r) %record (rf) %name r printline("Adjusting 32-bit real image for display: ") p=0; vmax=-100000000; vmin=100000000 %for i=0, 1, iffh_ht*iffh_wid-1 %cycle r == record(from+p); p=p+4 vmax=r_r %if r_r>vmax; vmin=r_r %if r_rvmax; vmin=v %if v>s; p=p+2; q=q+1 %repeat %finish printstring(" Shift by ".itos(offset, -1)) newline %end %routine iff 2 to 8(%record (iffhdr fm) %name iffh, %integer from, to) !Expand packed booleans to array of 0's and 255's %integer i, max, k, mask %label l1,l2,l5,l6 printline("Adjusting boolean image for display") max = (iffh_ht * iffh_wid)>>3 !! %for i=max-1, -1, 0 %cycle !! mask=128 !! %for k=7,-1,0 %cycle !! %if byteinteger(from)&mask=0 %then byteinteger(to)=255 %else byteinteger(to)=0 !! to=to+1; mask=mask>>1 !! %repeat !! from=from+1 !! %repeat *move.l from,a0 *move.l to,A1 *move.l max,d3 *subq.l #1,max l1: *move.l #128,d1 *moveq #7,d2 l2: *move.b 0(a0),d0 *and.l d1,d0 *bne l6 *move.b #255,d0 *bra l5 l6: *clr.b d0 l5: *move.b d0,(a1)+ *lsr.l #1,d1 *dbra d2, l2 *addq.l #1,a0 *dbra d3, l1 %end %routine iff sample(%record (iffhdr fm) %name iffh, %integer ad, xsam, ysam) %integer i, j, xmax, ymax, from, to xmax = iffh_wid//xsam; xmax=xmax+1 %if xmax*xsam # iffh_wid ymax = iffh_ht//ysam; ymax=ymax+1 %if ymax*ysam # iffh_ht to = ad %for i=0, 1, ymax-1 %cycle from = ad+i*iffh_wid*ysam %for j=0, 1, xmax-1 %cycle byteinteger(to) = byteinteger(from); to=to+1; from=from+xsam %repeat %repeat %end %routine iff disp(%string (255) infile, outfile, %integer imageno) %integer bbase, wbase, base, images, a %integer i,j,c,rc,xoff,yoff,ht,wid %ownrecord (iffhdr fm) iffhdr %half %array CM (0:255) %constinteger w=688, h=512, h2=h//2, w2=w//2, w3=w//3 !Entries are origin and window size !This array defines windows on the screen (across the table) !for simultaneous display of 1.. 2.. etc. images (down the table) %ownintegerarray win(0:4*maxwins*maxwins-1) = %c 0,0, w,h, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, w2,h, w2,0, w2,h, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, w2,h2, w2,0, w2,h2, 0,h2, w,h2, 0,0, 0,0, 0,0, 0,0, 0,0, w2,h2, w2,0, w2,h2, 0,h2, w2,h2, w2,h2, w2,h2, 0,0, 0,0, 0,0, w2,h2, w2,0, w2,h2, 0,h2, w3,h2, w3,h2, w3,h2, 2*w3,h2, w3,h2 printline("Graphics system inaccessible") %and %return %unless graphics present rc = iff open file(infile, iffhdr, iff read) printline("Not a valid IFF file -".iff error(rc)) %and %return %if rc#0 iffhdr_mapaddr = addr(cm(0)) rc = iff read header(iffhdr) %if rc=0 %start ht = iffhdr_ht; wid=iffhdr_wid max=ht*wid ;!No of bytes in original expanded image max=max*2 %if iffhdr_datatype & 7 = 1 ;!16-bit words max=max*4 %if iffhdr_datatype & 7 = 4 %or iffhdr_datatype & 7 = 5 ;!32-bit max=max//8 %if iffhdr_datatype & 7 = 2 ;!Packed booleans iff show header(iffhdr, 0) base=0; images=1 images=iffhdr_stereo+1 %if 0<=iffhdr_stereo<=maxwins-1 a = heapget(images * max) %if imageno=0 %start ;!He wanted the lot %for i=0, 1, images-1 %cycle rc = iff read image(iffhdr, a+base) printline("Invalid IFF image".itos(rc,2)) %if rc#0 base = base + max %repeat %else images=1 %cycle rc = iff read image(iffhdr, a) imageno=imageno-1 %repeatuntil imageno=0 %finish %finishelse printline("Invalid IFF header") iff close file(iffhdr) ;!finished with file %return %if rc#0 %if iffhdr_datatype & 7 # 0 %start ;!Non-byte images. Reformat to bytes. wbase=a %if iffhdr_datatype & 7 = 2 %start ;!Packed booleans !This EXPANDS the image so we can't do it in-place. bbase = heapget(images * iffhdr_wid * iffhdr_ht); base = bbase %else bbase=a %finish %for i=0, 1, images-1 %cycle %if iffhdr_datatype & 7 = 1 %start ;!16-bit image iff 16 to 8(iffhdr, wbase, bbase) %elseif iffhdr_datatype & 7 = 2 ;!Packed booleans iff 2 to 8(iffhdr, wbase, bbase) %elseif iffhdr_datatype & 7 = 4 iff 32 to 8(iffhdr, wbase, bbase) %elseif iffhdr_datatype & 7 = 5 iff real to 8(iffhdr, wbase, bbase) %finish wbase=wbase+max; bbase=bbase+iffhdr_wid*iffhdr_ht %repeat %if iffhdr_datatype & 7 = 2 %then heapput(a) %and a=base iffhdr_datatype = 0 ;!Bytes %finish base=a %for i=0, 1, images-1 %cycle iff flip(iffhdr, base); base=base+iffhdr_ht*iffhdr_wid %repeat Setup %if iffhdr_maplen=0 %start !No colour map - construct grey scale %for i=0,1,255 %cycle; c = i>>3; CM(i) = (c<<5 + c)<<5 + c; %repeat %elseif iffhdr_datatype & 7 = 2 ;!Booleans - use 0 (black) and 255 (white) cm(0) = 0; cm(255) = 16_7FFF %finish Update Colour Map (cm(0)) Clear j=0 offset(0,0) %for i=0, 1, images-1 %cycle wid=iffhdr_wid; ht=iffhdr_ht xbase(i)=win(20*images+i*4-20); ybase(i)=win(20*images+i*4+1-20) xsize(i)=win(20*images+i*4+2-20); ysize(i)=win(20*images+i*4+3-20) iwid(i)=wid; iht(i)=ht %if wid > xsize(i) %or ht > ysize(i) %start printline("Image ".itos(i,-1)." too big for window.") j = 1 %finish %repeat %if j#0 %start ;!Can't put them all on the screen at once, so... printline("Images will be displayed sequentially") %for i=0, 1, images-1 %cycle xbase(i)=0; ybase(i)=0; wid=iffhdr_wid; ht=iffhdr_ht %if iffhdr_wid<=w %and iffhdr_ht<=h %start !If it's displayable set limits = screen to preserve centring xsize(i)=w; ysize(i)=h; iwid(i)=wid; iht(i)=ht %elseif wid<=1024 %and ht<=1024 !If it's less than the full framestore plot at bottom LH !and let him pan round it. xsize(i)=wid; ysize(i)=ht; iwid(i)=wid; iht(i)=ht %else !Sample it down so it fits. xsam = (iffhdr_wid-1)//1024+1 ysam = (iffhdr_ht-1)//1024+1 printstring("Image larger than frame buffer. Sampling ") write(xsam,-1); printstring(" * "); write(ysam, -1); newline iff sample(iffhdr, a, xsam, ysam) !Correct sizes. Adjust for "fence-post" condition. iwid(i) = iffhdr_wid//xsam; iwid(i)=iwid(i)+1 %if iwid(i)*xsam # iffhdr_wid iht(i) = iffhdr_ht//ysam; iht(i)=iht(i)+1 %if iht(i)*ysam # iffhdr_ht %if iwid(i)<=688 %then xsize(i)=688 %else xsize(i)=iwid(i) %if iht(i)<=512 %then ysize(i)=512 %else ysize(i)=iht(i) %finish %repeat %finish base=a %for i=0, 1, images-1 %cycle xoff=xbase(i)+(xsize(i)-iwid(i))>>1; yoff=ybase(i)+(ysize(i)-iht(i))>>1 printstring("Image"); write(i, 2); printstring(" at [") write(xoff, 3); printsymbol(','); write(yoff, 3) printstring("] in "); write(xsize(i), 3); printstring(" * "); write(ysize(i), 3) printstring(" window at [") write(xbase(i), 3); printsymbol(','); write(ybase(i), 3); printsymbol(']') newline col fill(xoff, yoff, xoff+iwid(i)-1, yoff+iht(i)-1, byteinteger(base)) %if j#0 %start iffhdr_xoff = xoff; iffhdr_yoff=yoff moveit(iffhdr,a,i,i,j) clear newline %finish base=base + wid*ht %repeat %if j=0 %start iffhdr_xoff = xoff; iffhdr_yoff=yoff moveit(iffhdr,a,0,images-1,j) %finish heapput(a) %end param="" %and infile=cli param %unless cli param -> infile.("-").param outfile="" %unless infile -> infile.("/").outfile %if param="" %then imageno=0 %else imageno=stoi(param) iff disp(infile, outfile, imageno) %endofprogram