Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-04 - decus/20-0110/mintrp.sai
There are 2 other files named mintrp.sai in the archive. Click here to see a list.
ENTRY;
COMMENT
.SOSPAGE_1
.SEC(MINTRP - PROC10 Mask Operation Interpreter)
.index(MINTRP - PROC10 Mask Operation Interpreter)
.;
BEGIN "MINTRP.SAI"


COMMENT




               P. LEMKIN, R. GORDON, B. SHAPIRO

                     IMAGE PROCESSING UNIT

           DIVISION OF CANCER BIOLOGY AND DIAGNOSIS
                   NATIONAL CANCER INSTITUTE
                 NATIONAL INSTITUTES OF HEALTH
                      BETHESDA, MD 20014


                         301-496-2394

Oct 12, 1976 - Lemkin, removed SMSG/DEBUG
Revised Aug 25, 1976 - Lemkin, MSLICE density
Revised Aug 24, 1976 - Lemkin, MSLICE density
Revised Aug 23, 1976 - Lemkin, revised SMSG comments
Revised Aug 6, 1976 - Lemkin,  removed POLYGON command
Revised May 28, 1976  fixed read filelookup
Revised July 7, 1976  fixed read filelookup
Revised May 27, 1976  CHANGED - TO MINUS
Revised May 24, 1976 - Lemkin READ
Revised May 22, 1976 - Lemkin READ/WRITE, MCIRCLE
Revised May 17, 1976 - Lemkin fixed sip5,6 xfer
Revised April 19, 1976 - Lemkin fixed PERIMETER
Revised April 14, 1976 - Lemkin - changed CIRCLE to MCIRCLE cmd

;
COMMENT
.ss(MINTRP REQUIRE files)
.INDEX(MINTRP REQUIRE files)
.;
Comment
"	================================"
"	=    R E Q U I R E             ="
"	================================"

"	The following files are required for  use  by  PROC10.
They all reside in the Image Processing Unit's common user area
";

Comment
 note the following REQ's are for debugging and will be removed;
Require "ARINFO.REQ" source!file;

Comment	 Permanent REQ's;
Require "DEFINE.REQ" source!file;
Require "GETABL.REQ" source!file;
Require "IO.REQ" source!file;
Require "SYS:DISPRM.SAI" source!file;
Require "PPAK.REQ" source!file;
Require "CVT.REQ" source!file;
Require "BOUND.REQ" source!file;
Require "DARRAY.REQ" source!file;
Require "PIXDMP.REQ" source!file;

"	The following require  files  are  used  to  link  this
interpreter with PROC10 itself"
Require "PRCMAX.REQ" source!file;
Require "PRCINV.REQ" source!file;
Require "PRCWRK.REQ" source!file;
COMMENT
.ss(Procedure MASK!ASSIGNMENT)
.INDEX(Procedure MASK!ASSIGNMENT)
.;

Internal Procedure MASK!ASSIGNMENT;
Begin "MASK!ASSIGNMENT"

String
	s1,
	s2,
	s3,
	s,
	ss,
	sss;

Integer Array 
	xy!list[1:2,1:100];
Own integer
	nvertices,
	side,
	zcenter,
	row!start,
	column!start,
	row!square,
	column!square,
	row!circle,
	column!circle;

Own Real
	radius,
	radius!of!sphere,
	radius2;
Integer
	i,
	j,
	r,
	c,
	row,
	column,
	ival,
	jval,
	msk!index1,
	msk!index2,
	msk!index3,
	index;

Label mask!a!dispatch;

Real val;

"	Find the maskoperator index"
		For index_1 Step 1 Until max!number!maskops Do
			If equ(cmd, lgl!mops[index]) 
				Then Done;

If db=2 Then Goto mask!a!dispatch;


"see if have a mask anywhere"

	mask1_mask2_mask3_none;

"	Get the output mask if the command is not output nullary"
If Equ(GUESSER(cmd,lgl!noutput!ops), null)
	Then
	Begin "Get the output mask"
	If (mask3_GET!MASK(sout)) = none Then Return;

"	copy the mask index"
	msk!index3_m!index;

"	Get the mask output title if non-null and not READ"
	If not Equ(sout,null) Then
	If Mask!title[msk!index3]=null and not Equ(cmd,"READ")
		Then
		If auto!title Then mask!title[msk!index3]_strcopy

		Else
		SBOUND(Mask!title[msk!index3],"any",
			"Mask "&sout&" title", sout&" title");
	End "Get the output mask"
	Else
	If not Equ(cmd,"WRITE")
		Then
		Begin "shift args right"
"		Shift the input  args  right  since  sout  is
		really sip1 etc."
		sip6_sip5;
		sip5_sip4;
		sip4_sip3;
		sip3_sip2;
		sip2_sip1;
		sip1_sout;
		sout_null;
		End "shift args right";

If Equ(GUESSER(cmd,lgl!ninput!ops),null) 
	Then
	Begin "Get input mask"
	 If (sip1_GUESSER(sip1,lgl!mnames)) =null
		Then Begin "Bad input mask"
		Outstr("Bad input mask"&crlf);
		DEL!MASK(sout);
		Return;
		End "Bad input mask";

	If (mask1_GET!MASK(sip1))=none
		Then Return;
	msk!index1_m!index;
	End "Get input mask";



"	If input2 is a mask then get it"
	If not Equ(GUESSER(sip2,lgl!mnames),null)
		Then 
		If (mask2_GET!MASK(sip2))=none
			Then Return;
	msk!index2_m!index;


"	DISPATCH AND TEST FOR UNARY IN EACH CASE"
mask!a!dispatch:  CASE (index-1) of
	Begin "DO MASKOPERATIONS"
Begin "1 AND"
COMMENT
.sss(AND)
.INDEX(AND)
.;
	
		If (mask2 = none)
			Then Begin "Not enough"
				outstr("Bad 2nd input mask."&crlf);
				DEL!MASK(sout);
				Return;
			     End "Not enough";
		PMAND(Datum(mask1),Datum(mask2),Datum(mask3));
		End "1 AND";

Begin "2 OR"
COMMENT
.sss(OR)
.INDEX(OR)
.;
	
		If (mask2 = none)
			Then Begin "Not enough"
				outstr("Bad 2nd input mask."&crlf);
				DEL!MASK(sout);
				Return;
			     End "Not enough";
		PMOR(Datum(mask1),Datum(mask2),Datum(mask3));
		End "2 OR";

Begin "3 MINUS"
COMMENT
.sss(SUB)
.INDEX(SUB)
.;
	
		If (mask2 = none)
			Then Begin "Not enough"
				outstr("Bad 2nd input mask."&crlf);
				DEL!MASK(sout);
				Return;
			     End "Not enough";
		PMSUB(Datum(mask1),Datum(mask2),Datum(mask3));
		End "3 MINUS";

Begin "4 COPY"
COMMENT
.sss(COPY)
.INDEX(COPY)
.;
	
		PMCOPY(Datum(mask1),Datum(mask3));
		End "4 COPY";

Begin "5 NOT"
COMMENT
.sss(COMPLEMENT)
.INDEX(COMPLEMENT)
.;
	
		PMCOMPLEMENT(Datum(mask1),Datum(mask3));
		End "5 NOT";

Begin "6 ZERO"
COMMENT
.sss(ZERO)
.INDEX(ZERO)
.;
	
		PMZERO(Datum(mask3));
		End "6 ZERO";

Begin "7 READ"
COMMENT
.sss(READ)
.INDEX(READ)
.;
	
		PFRAME("SAVE");
"		Get the input file name if specified in sip1
		else ask for it"
		If not Equ(sip1,null) 
			Then 
			Begin "From args"
			file!name_sip1&proj!programmer;
"			Lookup the file"
			s_dev!name;
			If s=":" or s=null
				Then s_"DSK"
				Else s_s[1 to inf-1];
			Open(i_Getchan,s,0,0,0,1,j,flag);
			Lookup(i,file!name,flag);
			Release(i);
			file!name_dev!name&file!name;
			End "From args"
			Else
			flag_true;

			If flag
				Then
				Begin "Not found"
				Outstr("File not found."&crlf);
				Return;
				End "Not found";

		If sip2 Neq "N"
		 Then
		 Begin "Check size"
"		Get the header and check to see if it is non 
		256x256 size"
		header[0]_1;
		GETDDTG(file!name,header);
		CLOSEINDATA;

"		See if the type is neq current size"
		If header[80] neq imsiz
			Then
			Begin "change mask size"
			Outstr("Computing size ="&cvs(imsiz+1)&
			   " inconsistant with file size ="&
			   cvs(header[80]+1)&crlf&
			   "To read it in, the current mask "&
			   "must be deleted."&crlf);
			If not DEL!MASK(sout) 
				Then
				Begin "ok, make new mask"
				ival_(16 Max header[80]) Min 256;
				PINI(trunc!max,ival);
				mask3_GET!MASK(sout);
				msk!index3_m!index;
				End "ok, make new mask";
			End "change mask size";
		 End "Check size";

"		Setup NUMBER option if exists"
		header[0]_sip2;

		outstr("Reading in mask "&file!name&crlf);

		If flag_GETBMASK(Datum(mask3), file!name,
			mask!title[msk!index3], header)
				Then 
				outstr("Bad mask file header"&crlf);
"		print the mask title"
		outstr("Title:"&crlf&mask!title[msk!index3]&crlf);
		PFRAME("RESTORE");
		If not flag Then Return 
			Else DEL!mask(sout);
		End "7 READ";

Begin "8 WRITE"
COMMENT
.sss(WRITE)
.INDEX(WRITE)
.;
	
		If not Equ(sout,null)
			Then outfile_dev!name&sout&proj!programmer
			Else
			While FBOUND(outfile,"any","Output file",
				"file") Do
				  	outstr("file " & outfile & 
					   " already exists" & crlf);
		If  equ(mask!title[msk!index1],null)
			Then SBOUND(mask!title[msk!index1],"any",
					"mask title","Title");
		outstr("Writing mask " & outfile & crlf);
"		Force it to generate a mask header"
		header[0]_0;
		PUTBMASK(Datum(mask1),outfile,mask!title[msk!index1],
			header);
		outstr(crlf);
		End "8 WRITE";

Begin "9 DELETE"
COMMENT
.sss(DELETE)
.INDEX(DELETE)
.;
	
		DEL!MASK(sout);
		End "9 DELETE";
Begin "10 MCIRCLE"
COMMENT
.sss(MCIRCLE)
.INDEX(MCIRCLE)
.;
	
		If not (sip1 = null)
			Then
			radius_(1 max Realscan(sip1,flag)) 
				min imsiz
			Else
			BOUND(1,radius,imsiz,"radius",null);
		radius2_radius^2;

		If not (sip2 = null)
			Then
			row!circle_(firstrow max 
				Intscan(sip2,flag)) min lastrow
			Else
			IBOUND("-inf",row!circle,"inf",
				"center row","row");
	
		If not (sip3 = null)
			Then
			column!circle_(firstcolumn max 
				Intscan(sip3,flag)) min
					 lastcolumn
			Else
			IBOUND("-inf",column!circle,"inf",
				"center column", "column");
		PMCIRCLE(Datum(mask3),row!circle,column!circle,radius);
		End "10 MCIRCLE";

Begin "11 RECTANGLE"
COMMENT
.sss(RECTANGLE)
.INDEX(RECTANGLE)
.;
	
		If not(sip1=null)
			Then
			row!side_(0 Max Intscan(sip1,flag)) Max
					imsiz
			Else
			IBOUND(1,row!side,imsiz,"number of rows",
				"# rows");

		If not (sip2=null)
			Then
			column!side_(0 Max Intscan(sip2,flag)) Max
					imsiz
			Else
			IBOUND(1,column!side,imsiz,
				"number of columns", "# columns");

		If not (sip3=null)
			Then
			rect!row!center_
				(0 Max Intscan(sip3,flag)) Max imsiz
			Else
			IBOUND(row!side,rect!row!center,imsiz-row!side,
				"center row","row");

		If not (sip4=null)
			Then
			rect!column!center_
				(0 Max Intscan(sip4,flag)) Max imsiz
			Else
			IBOUND(column!side,rect!column!center,
				imsiz-column!side,
				"center column", "column");

		PMRECTANGLE(Datum(mask3), rect!row!center,
			 rect!column!center, row!side, column!side);
		End "11 RECTANGLE";

Begin "12 MSLICE"
COMMENT
.sss(MSLICE)
.INDEX(MSLICE)
.;
	Own Integer dmin, dmax;
	
		If (image1_GET!IMAGE(sip1))=none 
			Then return;

		If (sip2 neq "U")
			Then
			dmin_(0 max abs(Intscan(sip2,flag)))
				 min trunc!max
			Else
			dmin_thr!density;

		If (sip2 neq "U")
			Then
			dmax_(dmin max abs(Intscan(sip3,flag)))
					 min trunc!max
			Else
			dmax_trunc!max;
		PMSLICE(Datum(mask3),Datum(image1),dmin,dmax);
		End "12 MSLICE";

Begin "13 MSEGMENT"
COMMENT
.sss(MSEGMENT)
.INDEX(MSEGMENT)
.;
		Own Integer segment!number;
		If sip1=null Then Begin "get pix name"
			outstr("Generate mask from segment picture: ");
			sip1_UPLOWINCHWL;
			End "get pix name";
		If (image1_GET!IMAGE(sip1))=none Then return;

		If not Equ(sip2,null) 
			Then
			segment!number_(1 max Intscan(sip2,flag))
						min 253
			Else
			IBOUND(1,segment!number,253,
				"Segment number?","Seg #?");

		PMSEGMENT(Datum(mask3),Datum(image1),segment!number);
		End "13 MSEGMENT";

Begin "14 SPHERE"
COMMENT
.sss(SPHERE)
.INDEX(SPHERE)
.;
		If not (sip1 = null)
			Then
			zcenter_(mininteger max Intscan(sip1,flag) )
				min maxinteger
			Else
			IBOUND("-inf",zcenter,"inf",
			"distance of center from plane","z distance");

		If not (sip2 = null)
			Then
			radius!of!sphere_(minreal max 
				Realscan(sip2,flag)) 
					min maxreal
			Else
			BOUND(abs(zcenter),radius!of!sphere,
			"inf","radius of SPHERE","radius");

		radius_sqrt(radius!of!sphere^2-zcenter^2);
		If radius < 1 Then Return;
		radius2_radius^2;

		If not (sip3 = null)
			Then
			row!circle_(mininteger max 
				Intscan(sip3,flag)) 
					min maxinteger
			Else
			IBOUND("-inf",row!circle,"inf",
				"center row","row");

		If not (sip4 = null)
			Then
			column!circle_(mininteger max 
				Intscan(sip4,flag)) 
					min maxinteger
			Else
			IBOUND("-inf",column!circle,"inf","center column",
			"column");
		PMCIRCLE(Datum(mask3),row!circle,column!circle,radius);
		End "14 SPHERE";

Begin "15 SQUARE"
COMMENT
.sss(SQUARE)
.INDEX(SQUARE)
.;
		If not (sip1 = null)
			Then
			side_(mininteger max Intscan(sip1,flag)) 
				min maxinteger
			Else
			IBOUND(1,side,imsiz,"Size of side","Size");

		If not (sip2 = null)
			Then
			row!square_(mininteger max 
				Intscan(sip2,flag)) 
					min maxinteger
			Else
			IBOUND(-imsiz,row!square,imsiz,
				"center row","row");

		If not (sip3 = null)
			Then
			column!square_(mininteger max 
				Intscan(sip3,flag)) 
					min maxinteger
			Else
			IBOUND(-imsiz,column!square,imsiz,
				"center column","column");

		PMRECTANGLE(Datum(mask3), row!square, column!square,
			 side, side);
		End "15 SQUARE";

Begin "16 WHOLE"
COMMENT
.sss(WHOLE)
.INDEX(WHOLE)
.;
		For row_firstrow Step 1 Until lastrow Do
		    For column_firstcolumn Step 1 Until lastcolumn Do
			    MSK!PACK2D(Datum(mask3), row, column, 1);
		End "16 WHOLE";

Begin "17 AREA"
COMMENT
.sss(AREA)
.INDEX(AREA)
.;
		Integer area;
"		Compute area of mask by counting 1's"
		area_0;
		usemask_true;
		mskimage_mask1;
		For r_ firstrow step 1 until lastrow Do
		  For c_ firstcolumn step 1 until lastcolumn Do
		    If MSK!BOOL(r,c) Then area_area+1;
		Outstr("mask "&sip1&" AREA="&cvs(area)&
			" pixels"&crlf);
		End "17 AREA";

Begin "18 PERIMETER"
COMMENT
.sss(PERIMETER)
.INDEX(PERIMETER)
.;
		Real perimeter;
"		Compute PERIMETER of mask by counting 1's"
		perimeter_0;
		usemask_true;
		mskimage_mask1;
		For r_ firstrow+1 step 1 until lastrow-1 Do
		  For c_ firstcolumn+1 step 1 until lastcolumn-1 Do
		    If MSK!BOOL(r,c) 
		   	Then 
		        If (MSK!BOOL(r-1,c)=1 and
				    MSK!BOOL(r+1,c)=0) or
		           (MSK!BOOL(r,c-1)=1 and MSK!BOOL(r,c+1)=0) or
		           (MSK!BOOL(r+1,c)=1 and MSK!BOOL(r-1,c)=0)
				Then perimeter_perimeter+1
			Else
		        If 
			 (MSK!BOOL(r-1,c-1)=1 and MSK!BOOL(r,c-1)=0) or
			 (MSK!BOOL(r-1,c+1)=1 and MSK!BOOL(r-1,c)=0) or
			 (MSK!BOOL(r+1,c-1)=1 and MSK!BOOL(r,c-1)=0) or
			 (MSK!BOOL(r+1,c+1)=1 and MSK!BOOL(r+1,c)=0) 
				Then 
				perimeter_perimeter+sqrt(2);
		Outstr("mask "&sip1&" PERIMETER="&
			cvs(perimeter)&crlf);
		End "18 PERIMETER";



	End "DO maskOPERATIONS";

End "MASK!ASSIGNMENT";
End "MINTRP.SAI";