diff options
Diffstat (limited to 'pkg/images/tv/iis')
173 files changed, 15049 insertions, 0 deletions
diff --git a/pkg/images/tv/iis/README b/pkg/images/tv/iis/README new file mode 100644 index 00000000..1562fd6f --- /dev/null +++ b/pkg/images/tv/iis/README @@ -0,0 +1,3 @@ +CV -- Control video package. This is a prototype package, used to load images +into the image display (currently only the IIS), as well as to control the +display and read the display memory. diff --git a/pkg/images/tv/iis/blink.cl b/pkg/images/tv/iis/blink.cl new file mode 100644 index 00000000..5cc437e5 --- /dev/null +++ b/pkg/images/tv/iis/blink.cl @@ -0,0 +1,19 @@ +#{ BLINK -- Blink 2, 3, or 4 frames. + +# frame1,i,a,,,,Frame1 +# frame2,i,a,,,,Frame2 +# frame3,i,a,,,,Frame3 +# frame4,i,a,,,,Frame4 +# rate,r,h,1.,,,Blink rate (sec per frame) + +{ + if ($nargs == 3) { + _dcontrol (alternate = frame1 // " " // frame2 // " " // + frame3, blink+, rate=rate) + } else if ($nargs == 4) { + _dcontrol (alternate = frame1 // " " // frame2 // " " // + frame3 // " " // frame4, blink+, rate=rate) + } else { + _dcontrol (alternate = frame1 // " " // frame2, blink+, rate=rate) + } +} diff --git a/pkg/images/tv/iis/blink.par b/pkg/images/tv/iis/blink.par new file mode 100644 index 00000000..bccfa8f2 --- /dev/null +++ b/pkg/images/tv/iis/blink.par @@ -0,0 +1,5 @@ +frame1,i,a,,,,Frame1 +frame2,i,a,,,,Frame2 +frame3,i,a,,,,Frame3 +frame4,i,a,,,,Frame4 +rate,r,h,1.,,,Blink rate (sec per frame) diff --git a/pkg/images/tv/iis/cv.par b/pkg/images/tv/iis/cv.par new file mode 100644 index 00000000..c33dd032 --- /dev/null +++ b/pkg/images/tv/iis/cv.par @@ -0,0 +1,4 @@ +# Package parameters for CV. + +snap_file,f,a,,,,output file for snap image +textsize,r,a,1.0,,,character size diff --git a/pkg/images/tv/iis/cvl.par b/pkg/images/tv/iis/cvl.par new file mode 100644 index 00000000..c2eb9fab --- /dev/null +++ b/pkg/images/tv/iis/cvl.par @@ -0,0 +1,25 @@ +# Package parameters for CVL. +# All are from "display.par" + +image,f,a,,,,image to be displayed +frame,i,a,1,1,4,frame to be written into +border_erase,b,h,no,,,erase unfilled area of window +erase,b,h,yes,,,display frame being loaded +select_frame,b,h,yes,,,display frame being loaded +#repeat,b,h,no,,,repeat previous display parameters +fill,b,h,no,,,scale image to fit display window +zscale,b,h,yes,,,display range of greylevels near median +contrast,r,h,0.25,,,contrast adjustment for zscale algorithm +zrange,b,h,yes,,,display full image intensity range +nsample_lines,i,h,5,,,number of sample lines +xcenter,r,h,0.5,0,1,display window horizontal center +ycenter,r,h,0.5,0,1,display window vertical center +xsize,r,h,1,0,1,display window horizontal size +ysize,r,h,1,0,1,display window vertical size +xmag,r,h,1.,,,display window horizontal magnification +ymag,r,h,1.,,,display window vertical magnification +z1,r,h,,,,minimum greylevel to be displayed +z2,r,h,,,,maximum greylevel to be displayed +ztrans,s,h,linear,,,greylevel transformation (linear|log|none) +lutfile,f,h,"",,,name of textfile with user's transformation table +version,s,h,"14May85" diff --git a/pkg/images/tv/iis/doc/Cv.spc.hlp b/pkg/images/tv/iis/doc/Cv.spc.hlp new file mode 100644 index 00000000..0b30ae1c --- /dev/null +++ b/pkg/images/tv/iis/doc/Cv.spc.hlp @@ -0,0 +1,286 @@ +.help cv Jan86 tv.cv +The \fIcv\fR program is used to control the image display from within +\fIIRAF\fR. It differs from most \fIIRAF\fR programs since it has its +own prompt and its own internal "language". Each of the available commands +is described in the following paragraphs, but first a few comments on the +command structure seem in order. Commands are distinguished by their +first letter, except for a few instances where the second letter is needed. +The rest of the command name can be typed if you wish. Commands often +require specification of frames numbers, colors, quadrants, or numeric +values. In most cases, the order is unimportant, but, zoom, for instance, +does require the zoom power right after the command name. The order given +in the \fIhelp\fR command will always work. + +A frame list is indicated in the \fIhelp\fR listing with an \fBF\fR. This +is to be replaced in the typed command by an \fBf\fR followed (no spaces) +with a list of the pertinent image planes. Thus, \fBf1\fR means +\fIframe 1\fR while \fBf42\fR means \fIframes 4\fR +and \fI2\fR. In most cases, the leading \fBf\fR can be omitted. +The specification \fBfa\fR means \fIall frames\fR. In those +cases in the \fIhelp\fR menu where the frame specification is optional, +omitting the frame list is the same as typing \fBfa\fR; that is, operate +on \fIall\fR frames. + +A color specification is a \fBc\fR followed by a set of letters. +The letter \fBa\fR means \fIall\fR, just as in the frame specification. +The letters \fBr, b,\fR and \fBg\fR are the other possibilities for all +commands other than \fIdg\fR and \fIsnap\fR. For displaying graphics +planes (\fBdg\fR), the other possibilities are \fBy, p, m, w\fR which +stand for \fIyellow, purple, mauve,\fR and \fIwhite\fR. (\fIMauve\fR is +the wrong name and will get changed.) The \fIsnap\fR command accepts, in +addition to the standard three colors, \fBm, bw,\fR and \fBrgb\fR, which +stand for \fImonochrome, black and white,\fR and \fIfull color\fR. (See +the discussion under \fIsnap\fR for further explanation.) +An omitted color specification is the same as \fIall colors\fR. + +Quadrants are given by a \fBq\fR followed by numbers from the set one through +four, or the letter \fBa\fR as in the frame and color cases. Quadrants are +numbered in the standard way, with the upper right being \fI1\fR, the upper +left \fI2\fR, etc. Adjacent quadrants may be referenced by \fBt, b, l,\fR +and \fBr\fR, standing for \fItop, bottom, left,\fR and \fIright\fR. An +omitted quadrant specification is the same as \fIall quadrants\fR. Quadrants +are effective only if the split screen command has set the split point to +something other than the "origin". + +.ls \fBblink\fR N F (C Q) (F C Q) +The blink rate is given by \fBN\fR, which is in tenths of a second. Although +current timing routines in \fIIRAF\fR do not recognize partial seconds, +for the NOAO 4.2BSD UNIX implementation, a non-portable timing routine is +used so that tenth seconds are usable. +Erratic timing is pretty much the rule when the system load is large. +One frame must be given, +followed by any color or quadrant specification, and then +optionally followed by any number of similar triads. A specification of +\fI10 f12 f3 f3 f4\fR would display frames one and two for one second, then +frame three for two one second intervals, then frame 4, and then recycle. +The first blink cycle may appear somewhat odd as the code "settles in", +but the sequence should become regular after that (except for timing +problems due to system load). In split screen mode, it is necessary to +specify all the frames together with quadrants, which leads to a lot of +typing: The reason is that blink simply cycles through a series of +\fBdi\fR commands, and hence it requires the same information as that +command. +.le +.ls \fBcursor\fR [on off F] +This command is used to turn the cursor on or off, and to read coordinates +and pixel values from a frame. Pixel coordinates for a feature are those +of the image as loaded into the display, and do not change as the image +is panned or zoomed. Fractional pixel positions are given for zoomed +images, with a minimum number of decimal places printed (but the same number +for both the \fIx\fR and \fIy\fR coordinates). +For an unpanned, unzoomed image plane, the lower left corner +of the \fIscreen\fR is (1,1) +even if the image you loaded is smaller than 512x512, occupies only +a portion of the display screen, and does not extend to the lower left +corner of the screen. This defect will likely be remedied +when the \fIcv\fR package is properly integrated into \fIIRAF\fR. +Pixel information can be read from a frame that is not being displayed. +.le +.ls \fBdi\fR F (C Q) [on off] +The \fId\fRisplay \fIi\fRmage command turns specified frames on (or off). +Turning a frame off does not erase it. A frame need not have all colors +turned on, nor appear in all quadrants of a split screen display. +.le +.ls \fBdg\fR C (F Q) [on off] +The \fId\fRisplay \fIg\fRraphics command turns specific graphics planes +on or off. For the IIS display, neither the frame nor the quadrant +parameters are relevant. A side-effect of this command is that it +resets the graphics hardware to the \fIcv\fR standard: red cursor and +seven graphics planes, each colored differently. If the display is in +a "weird" state that is not cured with the \fIreset r/t\fR commands, +and a \fIreset i\fR would destroy images of interest, try a \fIdg ca on\fR +command followed by \fIdg ca off\fR. +.le +.ls \fBerase\fR [F all graphics] +This command erases the specified frame, or all the graphics planes, or +all data planes. The command \fBclear\fR is a synonym. +.le +.ls \fBmatch\fR (o) (F) (C) (to) (F) (C) +This command allows the user to copy a look-up table to a specified set +of tables, and hence, to match the mapping function of frames (and/or +colors) to a reference table. If the \fBo\fR parameter is omitted, the +match is among the look-up tables associated with particular frames; +otherwise, the \fIouput\fR tables are used (hence, the \fBo\fR). In the +latter case, only colors are important; the frame information should +be omitted. For the individual frame tables, colors can be omitted, in +which case a match of frame one to two means to copy the three tables +of frame two (red, green, and blue) to those of frame one. Only one +reference frame or color should be given, but \fImatch f23 cgb f1 cr\fR +is legal and means to match the green and blue color tables of both +frames two and three to the red table of frame one. +.le +.ls \fBoffset\fR C N +The value N, which can range from -4095 to +4095 is added to the data +pipeline for color \fBC\fR, thus offsetting the data. This is useful +if one needs to change the data range that is mapped into the useful part +of the output tables. +.le +.ls \fBpan\fR (F) +When invoked, this command connects the trackball to the specified frames +and allows the user to move (pan/roam/scroll) the image about the screen. +This function is automatically invoked whenever the zoom factor is changed. +.le +.ls \fBpseudo\fR (o) (F C) (rn sn) +Look-up tables are changed with the \fIwindow\fR and the \fIpseudocolor\fR +commands. Windowing provides linear functions and is discussed under that +command; \fIpseudo\fR provides pseudo-coloring capabilities. Pseudo-color +maps are usually best done in the output tables, rather than in the +look-up tables associated with particular frames; hence, \fBps o\fR is +the more likely invocation of the start of the command line. A color +(or colors) can be specified for "output" pseudocolor, in which case, only +those colors will be affected. For frame look-up tables, +the frame must be specified. + +Two mappings are provided. One uses a set of randomly selected colors +mapped to a specified number of pixel value ranges. The other uses +triangle color mappings. The former is invoked with the \fI(rn sn)\fR +options. In this case, the number following \fBr\fR gives the number of +ranges/levels into which the input data range is to be divided; to +each such range, a randomly selected color is assigned. The number +following \fBs\fR is a seed for the random number generator; changing +this while using the same number of levels gives different color mappings. +The default seed is the number of levels. If only the seed is given (\fBr\fR +omitted), the default number of levels is 8. This mapping is used when +a contour type display is desired: each color represents an intensity range +whose width is inversely proportional to the number of levels. + +The triangle mapping uses a different triangle in each of the three look-up +tables (either the sets associated with the specified frames, or the output +tables). The initial tables map low intensity to blue, middle values to +green, and high values to red, as shown in the diagram. (The red and blue +triangles are truncated as their centers are on a table boundary.) + +Once invoked, the program then allows the user to adjust the triangle +mapping. In +response to the prompt line, select the color to be changed and move the +trackball: the center of the triangle is given by the \fIx\fR cursor +coordinate and the width by the \fIy\fR coordinate. Narrow functions +(small \fIy\fR) allow one to map colors to a limited range of intensity. +When the mapping is satisfactory, a press of any button "fixes" the +mapping and the user may then either select another color or exit. +Before selecting a color, place the cursor at approximately the default +position for the mapping (or where it was for the last mapping of that +color under the current command); otherwise, the color map will change +suddenly when the color is selected via the trackball buttons. +.le +.ls \fBrange\fR N (C) (N C ...) +This command changes the range function in the specified color pipeline +so that the data is scaled by (divided by) the value \fBN\fR. For the +IIS, useful range values are 1,2,4 and 8; anything else will be changed +to the next lowest legal value. +.le +.ls \fBreset\fR [r i t a] +Various registers and tables are reset with this command. If the \fBr\fR +option is used, the registers are reset. This means that zoom is set to +one, all images are centered, split screen is removed, the range values are +set to one and the offset values are set to zero. Also, the cursor is +turned on and its shape is set. Option \fBi\fR causes all the image and +graphics planes to be erased and turned off. Option \fBt\fR resets all +the look-up tables to their default linear, positive slope, form, and +removes any color mappings by making all the output tables the same, and +all the frame specific tables the same. Option \fBa\fR does \fIall\fR +the above. +.le +.ls \fBsnap\fR (C) +This command creates an \fIIRAF\fR image file whose contents are a +512x512 digital snapshot of the image display screen. If no color +is specified, +or if \fIcm\fR (color monochromatic) is given, +the snapshot is of the \fIblue\fR image, which, if you +have a black and white image, is the same as the red or the green +image. Specifying \fBcg\fR for instance will take a snapshot of the +image that you would get had you specified \fIcg\fR for each frame +turned on by the \fIdi\fR command. Color is of interest only when +the window or pseudo color commands have made the three colors distinguishable. +If the "snapped" image is intended to be fed to the Dicomed film +recorder, a black and white image is all that is usually provided and so +a color snap is probably not appropriate. +In the case of the "no color/monochromatic" snap, the graphics planes are +all added together, while, if a real color is given, only the graphics +planes that have some of that color are included in the image. +The color \fBrgb\fR can be +given, in which case the red, green, and blue images are weighted equally +to produce a single image file. This image does not represent well what +you see, partly because of the equal weight given all colors: some +mapping of eye sensitivity is probably what is required, but it is not +implemented. + +The program operates by first determining zoom, pan, offset, tables, etc, +and, for each quadrant of the split screen, which images planes are active. +Then, for each line of the display, those images are read out from the display's +memory and the transformations done in hardware are duplicated pixel by pixel +in software. The word "active" needs a bit of explanation. Any image plane +whose pixels are contributing to the image is active. No image is active if +it has been turned off (by the \fIdi\fR) command (or if all images were +turned off and the one of interest not subsequently turned back on). If the +image is all zeroes, or if it is not but split screen is active and the +part of the image being displayed is all zeroes, it is not contributing to +the output. However, the snap program cannot tell that an active image is +not contributing anything useful, +and so it dutifully reads out each pixel and adds zeroes to the output. +The moral of this is that frames of no interest should be (turned) off before +snap is called (unless you don't have anything better to do than wait for +computer prompts). When split screen is active, frames are read only for +the quadrants in which they are active. + +The fastest snaps are for single images that are zoomed but not panned +and which are displayed (and snapped) in black and white, or snapped +in a single color. +.le +.ls \fBsplit\fR [c o px,y nx,y] +This command sets the split screen point. Option \fBc\fR is shorthand for +\fIcenter\fR, which is the normal selection. Option \fBo\fR stands for +\fIorigin\fR, and is the split position that corresponds to no split screen. +If you wish to specify the split point in pixels, use the \fBpx,y\fR form, in +which the coordinates are given as integers. If you prefer to specify +the point in NDC (which range from 0 though 1.0), use the \fBnx,y\fR form +in which the coordinates are decimal fractions. + +A peculiarity of the IIS hardware is that if no split screen is desired, +the split point must be moved to the upper left corner of the display, rather +than to the lower left (the \fIIRAF\fR 1,1 position). This means that no +split screen (the \fBo\fR option, or what you get after \fBre r\fR) is really +split screen with only quadrant \fBfour\fR displayed: if you use the \fIdi\fR +command with quadrant specification, only quadrant 4 data will be seen. +.le +.ls \fBtell\fR +This command displays what little it knows about the display status. At +present, all it can say is whether any image plane is being displayed, and +if any are, what is the number of one of them. This rather weak performance +is the result of various design decisions both within \fIcv\fR and the +\fIIRAF\fR display code, and may be improved. +.le +.ls \fBwindow\fR (o) (F C) +This command operates just as the \fIpseudo\fR command, except that it +applies a linear mapping to the output look-up tables (if option \fBo\fR +is used) or to the frame specific tables. The mapping is controlled by +the trackball, with the \fIy\fR cursor coordinate supplying the slope +of the map, and \fIx\fR the offset. If different mappings are given to +each color, a form of pseudo-color is generated. +.le +.ls \fBwrite\fR [F C] text +This command writes the given text into either an image plane (or planes) +or into the specified color graphics bit plane(s). The user is prompted +to place the cursor at the (lower left) corner of the text, which is +then written to the right in roman font. The user is also asked for +a text size (default 1.0). If the text is written into a graphics +plane, and a \fBsnap\fR is requested with no color specification, then +text in any graphics plane will be included in the image. A color snap, +on the other hand, will include graphics text to the extent that the +text is displayed in that color. +Text written into an image plane +will have the same appearance as any "full on" pixel; that is, text +in an image plane is written at maximum intensity, +overwrites the image data, +and is affected by look-up tables, offsets, +and so forth, like any other image pixels. +.le +.ls \fBzoom\fR N (F) +This command zooms the display to the power given by \fBN\fR. For the +IIS, the power must be 1,2,4, or 8; anything else is changed to the next +lower legal value. The model 70 zooms all planes together. The center +of the zoom is determined by the cursor position relative to the first +frame specified (if none, the lowest numbered active one). Once the zoom +has taken place, the \fIpan\fR routine is called for the specified frames. +.le +.endhelp diff --git a/pkg/images/tv/iis/doc/blink.hlp b/pkg/images/tv/iis/doc/blink.hlp new file mode 100644 index 00000000..f1440ebf --- /dev/null +++ b/pkg/images/tv/iis/doc/blink.hlp @@ -0,0 +1,46 @@ +.help blink Jan86 images.tv.iis +.ih +NAME +blink -- Blink frames in the image display +.ih +USAGE +blink frame1 frame2 [frame3 [frame4]] +.ih +PARAMETERS +.ls frame1 +First frame in blink sequence. +.le +.ls frame2 +Second frame in blink sequence. +.le +.ls frame3 +Third frame in blink sequence. +.le +.ls frame4 +Fourth frame in blink sequence. +.le +.ls rate = 1. +Blink rate in seconds per frame. May be any fraction of a second. +.le +.ih +DESCRIPTION +Two or more frames are alternately displayed on the image display monitor +("stdimage") at a specified rate per frame. +.ih +EXAMPLES +To blink two frames: + + cl> blink 1 2 + +To blink three frames at a rate of 2 seconds per frame: + + cl> blink 3 1 2 rate=2 +.ih +BUGS +The blink rate is measured in +software and, therefore, will not be exactly even in a time sharing +environment. +.ih +SEE ALSO +cv +.endhelp diff --git a/pkg/images/tv/iis/doc/cv.doc b/pkg/images/tv/iis/doc/cv.doc new file mode 100644 index 00000000..d34ccaa0 --- /dev/null +++ b/pkg/images/tv/iis/doc/cv.doc @@ -0,0 +1,332 @@ +.TL +The "cv" Display Package +.AU +Richard Wolff +.DA +.PP +The \fIcv\fR program is used to control the image display from within +\fIIRAF\fR. It differs from most \fIIRAF\fR programs since it has its +own prompt and its own internal "language". Each of the available commands +is described in the following paragraphs, but first a few comments on the +command structure seem in order. Commands are distinguished by their +first letter, except for a few instances where the second letter is needed. +The rest of the command name can be typed if you wish. Commands often +require specification of frames numbers, colors, quadrants, or numeric +values. In most cases, the order is unimportant, but, zoom, for instance, +does require the zoom power right after the command name. The order given +in the \fIhelp\fR command will always work. +.PP +A frame list is indicated in the \fIhelp\fR listing with an \fBF\fR. This +is to be replaced in the typed command by an \fBf\fR followed (no spaces) +with a list of the pertinent image planes. Thus, \fBf1\fR means +.I "frame 1" +while \fBf42\fR means +.I "frames 4" +and \fI2\fR. In most cases, the leading \fBf\fR can be omitted. +The specification \fBfa\fR means \fIall frames\fR. In those +cases in the \fIhelp\fR menu where the frame specification is optional, +omitting the frame list is the same as typing \fBfa\fR; that is, operate +on \fIall\fR frames. +.PP +A color specification is a \fBc\fR followed by a set of letters. +The letter \fBa\fR means \fIall\fR, just as in the frame specification. +The letters \fBr, b,\fR and \fBg\fR are the other possibilities for all +commands other than \fIdg\fR and \fIsnap\fR. For displaying graphics +planes (\fBdg\fR), the other possibilities are \fBy, p, m, w\fR which +stand for \fIyellow, purple, mauve,\fR and \fIwhite\fR. (\fIMauve\fR is +the wrong name and will get changed.) The \fIsnap\fR command accepts, in +addition to the standard three colors, \fBm, bw,\fR and \fBrgb\fR, which +stand for \fImonochrome, black and white,\fR and \fIfull color\fR. (See +the discussion under \fIsnap\fR for further explanation.) +An omitted color specification is the same as \fIall colors\fR. +.PP +Quadrants are given by a \fBq\fR followed by numbers from the set one through +four, or the letter \fBa\fR as in the frame and color cases. Quadrants are +numbered in the standard way, with the upper right being \fI1\fR, the upper +left \fI2\fR, etc. Adjacent quadrants may be referenced by \fBt, b, l,\fR +and \fBr\fR, standing for \fItop, bottom, left,\fR and \fIright\fR. An +omitted quadrant specification is the same as \fIall quadrants\fR. Quadrants +are effective only if the split screen command has set the split point to +something other than the "origin". +.sp +.SH +\fBblink\fR N F (C Q) (F C Q) +.IP +The blink rate is given by \fBN\fR, which is in tenths of a second. Although +current timing routines in \fIIRAF\fR do not recognize partial seconds, +for the NOAO 4.2BSD UNIX implementation, a non-portable timing routine is +used so that tenth seconds are usable. +Erratic timing is pretty much the rule when the system load is large. +One frame must be given, +followed by any color or quadrant specification, and then +optionally followed by any number of similar triads. A specification of +\fI10 f12 f3 f3 f4\fR would display frames one and two for one second, then +frame three for two one second intervals, then frame 4, and then recycle. +The first blink cycle may appear somewhat odd as the code "settles in", +but the sequence should become regular after that (except for timing +problems due to system load). In split screen mode, it is necessary to +specify all the frames together with quadrants, which leads to a lot of +typing: The reason is that blink simply cycles through a series of +\fBdi\fR commands, and hence it requires the same information as that +command. +.SH +\fBcursor\fR [on off F] +.IP +This command is used to turn the cursor on or off, and to read coordinates +and pixel values from a frame. Pixel coordinates for a feature are those +of the image as loaded into the display, and do not change as the image +is panned or zoomed. Fractional pixel positions are given for zoomed +images, with a minimum number of decimal places printed (but the same number +for both the \fIx\fR and \fIy\fR coordinates). +For an unpanned, unzoomed image plane, the lower left corner +of the \fIscreen\fR is (1,1) +even if the image you loaded is smaller than 512x512, occupies only +a portion of the display screen, and does not extend to the lower left +corner of the screen. This defect will likely be remedied +when the \fIcv\fR package is properly integrated into \fIIRAF\fR. +Pixel information can be read from a frame that is not being displayed. +.SH +\fBdi\fR F (C Q) [on off] +.IP +The \fId\fRisplay \fIi\fRmage command turns specified frames on (or off). +Turning a frame off does not erase it. A frame need not have all colors +turned on, nor appear in all quadrants of a split screen display. +.SH +\fBdg\fR C (F Q) [on off] +.IP +The \fId\fRisplay \fIg\fRraphics command turns specific graphics planes +on or off. For the IIS display, neither the frame nor the quadrant +parameters are relevant. A side-effect of this command is that it +resets the graphics hardware to the \fIcv\fR standard: red cursor and +seven graphics planes, each colored differently. If the display is in +a "weird" state that is not cured with the \fIreset r/t\fR commands, +and a \fIreset i\fR would destroy images of interest, try a \fIdg ca on\fR +command followed by \fIdg ca off\fR. +.SH +\fBerase\fR [F all graphics] +.IP +This command erases the specified frame, or all the graphics planes, or +all data planes. The command \fBclear\fR is a synonym. +.SH +\fBmatch\fR (o) (F) (C) (to) (F) (C) +.IP +This command allows the user to copy a look-up table to a specified set +of tables, and hence, to match the mapping function of frames (and/or +colors) to a reference table. If the \fBo\fR parameter is omitted, the +match is among the look-up tables associated with particular frames; +otherwise, the \fIouput\fR tables are used (hence, the \fBo\fR). In the +latter case, only colors are important; the frame information should +be omitted. For the individual frame tables, colors can be omitted, in +which case a match of frame one to two means to copy the three tables +of frame two (red, green, and blue) to those of frame one. Only one +reference frame or color should be given, but \fImatch f23 cgb f1 cr\fR +is legal and means to match the green and blue color tables of both +frames two and three to the red table of frame one. +.SH +\fBoffset\fR C N +.IP +The value N, which can range from -4095 to +4095 is added to the data +pipeline for color \fBC\fR, thus offsetting the data. This is useful +if one needs to change the data range that is mapped into the useful part +of the output tables. +.SH +\fBpan\fR (F) +.IP +When invoked, this command connects the trackball to the specified frames +and allows the user to move (pan/roam/scroll) the image about the screen. +This function is automatically invoked whenever the zoom factor is changed. +.SH +\fBpseudo\fR (o) (F C) (rn sn) +.IP +Look-up tables are changed with the \fIwindow\fR and the \fIpseudocolor\fR +commands. Windowing provides linear functions and is discussed under that +command; \fIpseudo\fR provides pseudo-coloring capabilities. Pseudo-color +maps are usually best done in the output tables, rather than in the +look-up tables associated with particular frames; hence, \fBps o\fR is +the more likely invocation of the start of the command line. A color +(or colors) can be specified for "output" pseudocolor, in which case, only +those colors will be affected. For frame look-up tables, +the frame must be specified. +.IP +Two mappings are provided. One uses a set of randomly selected colors +mapped to a specified number of pixel value ranges. The other uses +triangle color mappings. The former is invoked with the \fI(rn sn)\fR +options. In this case, the number following \fBr\fR gives the number of +ranges/levels into which the input data range is to be divided; to +each such range, a randomly selected color is assigned. The number +following \fBs\fR is a seed for the random number generator; changing +this while using the same number of levels gives different color mappings. +The default seed is the number of levels. If only the seed is given (\fBr\fR +omitted), the default number of levels is 8. This mapping is used when +a contour type display is desired: each color represents an intensity range +whose width is inversely proportional to the number of levels. +.IP +The triangle mapping uses a different triangle in each of the three look-up +tables (either the sets associated with the specified frames, or the output +tables). The initial tables map low intensity to blue, middle values to +green, and high values to red, as shown in the diagram. (The red and blue +triangles are truncated as their centers are on a table boundary.) +.sp +.KS +.PS +B: box +move +G: box +move +R: box +move to B.sw left 0.375 +line dotted to B.nw +line dashed to B.s +move to G.sw +line dashed to G.n +line dashed to G.se +move to R.s +line dashed to R.ne +line dotted to R.se right 0.375 +"blue" at B.s below +"green" at G.s below +"red" at R.s below +.PE +.sp +.KE +.IP +Once invoked, the program then allows the user to adjust the triangle +mapping. In +response to the prompt line, select the color to be changed and move the +trackball: the center of the triangle is given by the \fIx\fR cursor +coordinate and the width by the \fIy\fR coordinate. Narrow functions +(small \fIy\fR) allow one to map colors to a limited range of intensity. +When the mapping is satisfactory, a press of any button "fixes" the +mapping and the user may then either select another color or exit. +Before selecting a color, place the cursor at approximately the default +position for the mapping (or where it was for the last mapping of that +color under the current command); otherwise, the color map will change +suddenly when the color is selected via the trackball buttons. +.SH +\fBrange\fR N (C) (N C ...) +.IP +This command changes the range function in the specified color pipeline +so that the data is scaled by (divided by) the value \fBN\fR. For the +IIS, useful range values are 1,2,4 and 8; anything else will be changed +to the next lowest legal value. +.SH +\fBreset\fR [r i t a] +.IP +Various registers and tables are reset with this command. If the \fBr\fR +option is used, the registers are reset. This means that zoom is set to +one, all images are centered, split screen is removed, the range values are +set to one and the offset values are set to zero. Also, the cursor is +turned on and its shape is set. Option \fBi\fR causes all the image and +graphics planes to be erased and turned off. Option \fBt\fR resets all +the look-up tables to their default linear, positive slope, form, and +removes any color mappings by making all the output tables the same, and +all the frame specific tables the same. Option \fBa\fR does \fIall\fR +the above. +.SH +\fBsnap\fR (C) +.IP +This command creates an \fIIRAF\fR image file whose contents are a +512x512 digital snapshot of the image display screen. If no color +is specified, +or if \fIcm\fR (color monochromatic) is given, +the snapshot is of the \fIblue\fR image, which, if you +have a black and white image, is the same as the red or the green +image. Specifying \fBcg\fR for instance will take a snapshot of the +image that you would get had you specified \fIcg\fR for each frame +turned on by the \fIdi\fR command. Color is of interest only when +the window or pseudo color commands have made the three colors distinguishable. +If the "snapped" image is intended to be fed to the Dicomed film +recorder, a black and white image is all that is usually provided and so +a color snap is probably not appropriate. +In the case of the "no color/monochromatic" snap, the graphics planes are +all added together, while, if a real color is given, only the graphics +planes that have some of that color are included in the image. +The color \fBrgb\fR can be +given, in which case the red, green, and blue images are weighted equally +to produce a single image file. This image does not represent well what +you see, partly because of the equal weight given all colors: some +mapping of eye sensitivity is probably what is required, but it is not +implemented. +.IP +The program operates by first determining zoom, pan, offset, tables, etc, +and, for each quadrant of the split screen, which images planes are active. +Then, for each line of the display, those images are read out from the display's +memory and the transformations done in hardware are duplicated pixel by pixel +in software. The word "active" needs a bit of explanation. Any image plane +whose pixels are contributing to the image is active. No image is active if +it has been turned off (by the \fIdi\fR) command (or if all images were +turned off and the one of interest not subsequently turned back on). If the +image is all zeroes, or if it is not but split screen is active and the +part of the image being displayed is all zeroes, it is not contributing to +the output. However, the snap program cannot tell that an active image is +not contributing anything useful, +and so it dutifully reads out each pixel and adds zeroes to the output. +The moral of this is that frames of no interest should be (turned) off before +snap is called (unless you don't have anything better to do than wait for +computer prompts). When split screen is active, frames are read only for +the quadrants in which they are active. +.IP +The fastest snaps are for single images that are zoomed but not panned +and which are displayed (and snapped) in black and white, or snapped +in a single color. +.SH +\fBsplit\fR [c o px,y nx,y] +.IP +This command sets the split screen point. Option \fBc\fR is shorthand for +\fIcenter\fR, which is the normal selection. Option \fBo\fR stands for +\fIorigin\fR, and is the split position that corresponds to no split screen. +If you wish to specify the split point in pixels, use the \fBpx,y\fR form, in +which the coordinates are given as integers. If you prefer to specify +the point in NDC (which range from 0 though 1.0), use the \fBnx,y\fR form +in which the coordinates are decimal fractions. +.IP +A peculiarity of the IIS hardware is that if no split screen is desired, +the split point must be moved to the upper left corner of the display, rather +than to the lower left (the \fIIRAF\fR 1,1 position). This means that no +split screen (the \fBo\fR option, or what you get after \fBre r\fR) is really +split screen with only quadrant \fBfour\fR displayed: if you use the \fIdi\fR +command with quadrant specification, only quadrant 4 data will be seen. +.SH +\fBtell\fR +.IP +This command displays what little it knows about the display status. At +present, all it can say is whether any image plane is being displayed, and +if any are, what is the number of one of them. This rather weak performance +is the result of various design decisions both within \fIcv\fR and the +\fIIRAF\fR display code, and may be improved. +.SH +\fBwindow\fR (o) (F C) +.IP +This command operates just as the \fIpseudo\fR command, except that it +applies a linear mapping to the output look-up tables (if option \fBo\fR +is used) or to the frame specific tables. The mapping is controlled by +the trackball, with the \fIy\fR cursor coordinate supplying the slope +of the map, and \fIx\fR the offset. If different mappings are given to +each color, a form of pseudo-color is generated. +.SH +\fBwrite\fR [F C] text +.IP +This command writes the given text into either an image plane (or planes) +or into the specified color graphics bit plane(s). The user is prompted +to place the cursor at the (lower left) corner of the text, which is +then written to the right in roman font. The user is also asked for +a text size (default 1.0). If the text is written into a graphics +plane, and a \fBsnap\fR is requested with no color specification, then +text in any graphics plane will be included in the image. A color snap, +on the other hand, will include graphics text to the extent that the +text is displayed in that color. +Text written into an image plane +will have the same appearance as any "full on" pixel; that is, text +in an image plane is written at maximum intensity, +overwrites the image data, +and is affected by look-up tables, offsets, +and so forth, like any other image pixels. +.SH +\fBzoom\fR N (F) +.IP +This command zooms the display to the power given by \fBN\fR. For the +IIS, the power must be 1,2,4, or 8; anything else is changed to the next +lower legal value. The model 70 zooms all planes together. The center +of the zoom is determined by the cursor position relative to the first +frame specified (if none, the lowest numbered active one). Once the zoom +has taken place, the \fIpan\fR routine is called for the specified frames. diff --git a/pkg/images/tv/iis/doc/cv.hlp b/pkg/images/tv/iis/doc/cv.hlp new file mode 100644 index 00000000..6f90d74d --- /dev/null +++ b/pkg/images/tv/iis/doc/cv.hlp @@ -0,0 +1,341 @@ +.help cv Jan86 images.tv.iis +.ih +NAME +cv -- Control image device and take snapshots +.ih +USAGE +cv +.ih +PARAMETERS +.ls snap_file +Output file for snap image. +.le +.ls textsize +Character size for added text strings. +.le +.ih +COMMANDS +The following commands are available. This list is also available when +running the task with the commands h(elp) or ?. + +.nf +--- () : optional; [] : select one; N : number; C/F/Q : see below +b(link) N F (C Q) (F (C Q)..) blink (N = 10 is one second) +c(ursor) [on off F] cursor +di F (C Q) [on off] display image +dg C (F Q) [on off] display graphics +e(rase) [N a(ll) g(raphics) F] erase (clear) +m(atch) (o) F (C) (to) (F) (C) match (output) lookup table +o(ffset) C N offset color (N: 0 to +- 4095) +p(an) (F) pan images +ps(eudo) (o) (F C) (rn sn) pseudo color mapping + rn/sn: random n/seed n +r(ange) N (C) (N C ...) scale image (N: 1-8) +re(set) [r i t a] reset display + registers/image/tables/all +sn(ap) (C) snap a picture +s(plit) [c o px,y nx,y] split picture +t(ell) tell display state +w(indow) (o) (F C) window (output) frames +wr(ite) [F C] text write text to frame/graphics +z(oom) N (F) zoom frames (N: 1-8) +x or q exit/quit +--- C: letter c followed by r/g/b/a or, for snap r,g,b,m,bw,rgb, +--- or for dg r/g/b/y/p/m/w, as 'cr', 'ca', or 'cgb' +--- F: f followed by a frame number or 'a' for all +--- Q: q followed by quadrant number or t,b,l,r for top, bottom,... +.fi +.ih +DESCRIPTION +The \fIcv\fR program is used to control the image display from within +\fIIRAF\fR. It differs from most \fIIRAF\fR programs since it has its +own prompt and its own internal "language". Each of the available commands +is described in the following paragraphs, but first a few comments on the +command structure seem in order. Commands are distinguished by their +first letter, except for a few instances where the second letter is needed. +The rest of the command name can be typed if you wish. Commands often +require specification of frames numbers, colors, quadrants, or numeric +values. In most cases, the order is unimportant, but, zoom, for instance, +does require the zoom power right after the command name. The order given +in the \fIhelp\fR command will always work. + +A frame list is indicated in the \fIhelp\fR listing with an \fBF\fR. This +is to be replaced in the typed command by an \fBf\fR followed (no spaces) +with a list of the pertinent image planes. Thus, \fBf1\fR means +\fIframe 1\fR while \fBf42\fR means \fIframes 4\fR +and \fI2\fR. In most cases, the leading \fBf\fR can be omitted. +The specification \fBfa\fR means \fIall frames\fR. In those +cases in the \fIhelp\fR menu where the frame specification is optional, +omitting the frame list is the same as typing \fBfa\fR; that is, operate +on \fIall\fR frames. + +A color specification is a \fBc\fR followed by a set of letters. +The letter \fBa\fR means \fIall\fR, just as in the frame specification. +The letters \fBr, b,\fR and \fBg\fR are the other possibilities for all +commands other than \fIdg\fR and \fIsnap\fR. For displaying graphics +planes (\fBdg\fR), the other possibilities are \fBy, p, m, w\fR which +stand for \fIyellow, purple, mauve,\fR and \fIwhite\fR. (\fIMauve\fR is +the wrong name and will get changed.) The \fIsnap\fR command accepts, in +addition to the standard three colors, \fBm, bw,\fR and \fBrgb\fR, which +stand for \fImonochrome, black and white,\fR and \fIfull color\fR. (See +the discussion under \fIsnap\fR for further explanation.) +An omitted color specification is the same as \fIall colors\fR. + +Quadrants are given by a \fBq\fR followed by numbers from the set one through +four, or the letter \fBa\fR as in the frame and color cases. Quadrants are +numbered in the standard way, with the upper right being \fI1\fR, the upper +left \fI2\fR, etc. Adjacent quadrants may be referenced by \fBt, b, l,\fR +and \fBr\fR, standing for \fItop, bottom, left,\fR and \fIright\fR. An +omitted quadrant specification is the same as \fIall quadrants\fR. Quadrants +are effective only if the split screen command has set the split point to +something other than the "origin". + +.ls \fBblink\fR N F (C Q) (F C Q) +The blink rate is given by \fBN\fR, which is in tenths of a second. Although +current timing routines in \fIIRAF\fR do not recognize partial seconds, +for the NOAO 4.2BSD UNIX implementation, a non-portable timing routine is +used so that tenth seconds are usable. +Erratic timing is pretty much the rule when the system load is large. +One frame must be given, +followed by any color or quadrant specification, and then +optionally followed by any number of similar triads. A specification of +\fI10 f12 f3 f3 f4\fR would display frames one and two for one second, then +frame three for two one second intervals, then frame 4, and then recycle. +The first blink cycle may appear somewhat odd as the code "settles in", +but the sequence should become regular after that (except for timing +problems due to system load). In split screen mode, it is necessary to +specify all the frames together with quadrants, which leads to a lot of +typing: The reason is that blink simply cycles through a series of +\fBdi\fR commands, and hence it requires the same information as that +command. +.le +.ls \fBcursor\fR [on off F] +This command is used to turn the cursor on or off, and to read coordinates +and pixel values from a frame. Pixel coordinates for a feature are those +of the image as loaded into the display, and do not change as the image +is panned or zoomed. Fractional pixel positions are given for zoomed +images, with a minimum number of decimal places printed (but the same number +for both the \fIx\fR and \fIy\fR coordinates). +For an unpanned, unzoomed image plane, the lower left corner +of the \fIscreen\fR is (1,1) +even if the image you loaded is smaller than 512x512, occupies only +a portion of the display screen, and does not extend to the lower left +corner of the screen. This defect will likely be remedied +when the \fIcv\fR package is properly integrated into \fIIRAF\fR. +Pixel information can be read from a frame that is not being displayed. +.le +.ls \fBdi\fR F (C Q) [on off] +The \fId\fRisplay \fIi\fRmage command selects frames to be displayed on the +monitor. If neither \fIon\fR or \fIoff\fR is given, the specified frames +are turned on and all others are turned off. Turning a frame on with +the \fIon\fR specification displays the frames along with whatever else +is present; that is the new frame is added to the display. Note that +turning a frame off does not erase it. A frame need not have all colors +turned on, nor appear in all quadrants of a split screen display. +.le +.ls \fBdg\fR C (F Q) [on off] +The \fId\fRisplay \fIg\fRraphics command turns specific graphics planes +on or off. For the IIS display, neither the frame nor the quadrant +parameters are relevant. A side-effect of this command is that it +resets the graphics hardware to the \fIcv\fR standard: red cursor and +seven graphics planes, each colored differently. If the display is in +a "weird" state that is not cured with the \fIreset r/t\fR commands, +and a \fIreset i\fR would destroy images of interest, try a \fIdg ca on\fR +command followed by \fIdg ca off\fR. +.le +.ls \fBerase\fR [F all graphics] +This command erases the specified frame, or all the graphics planes, or +all data planes. The command \fBclear\fR is a synonym. +.le +.ls \fBmatch\fR (o) (F) (C) (to) (F) (C) +This command allows the user to copy a look-up table to a specified set +of tables, and hence, to match the mapping function of frames (and/or +colors) to a reference table. If the \fBo\fR parameter is omitted, the +match is among the look-up tables associated with particular frames; +otherwise, the \fIouput\fR tables are used (hence, the \fBo\fR). In the +latter case, only colors are important; the frame information should +be omitted. For the individual frame tables, colors can be omitted, in +which case a match of frame one to two means to copy the three tables +of frame two (red, green, and blue) to those of frame one. Only one +reference frame or color should be given, but \fImatch f23 cgb f1 cr\fR +is legal and means to match the green and blue color tables of both +frames two and three to the red table of frame one. +.le +.ls \fBoffset\fR C N +The value N, which can range from -4095 to +4095 is added to the data +pipeline for color \fBC\fR, thus offsetting the data. This is useful +if one needs to change the data range that is mapped into the useful part +of the output tables. +.le +.ls \fBpan\fR (F) +When invoked, this command connects the trackball to the specified frames +and allows the user to move (pan/roam/scroll) the image about the screen. +This function is automatically invoked whenever the zoom factor is changed. +.le +.ls \fBpseudo\fR (o) (F C) (rn sn) +Look-up tables are changed with the \fIwindow\fR and the \fIpseudocolor\fR +commands. Windowing provides linear functions and is discussed under that +command; \fIpseudo\fR provides pseudo-coloring capabilities. Pseudo-color +maps are usually best done in the output tables, rather than in the +look-up tables associated with particular frames; hence, \fBps o\fR is +the more likely invocation of the start of the command line. A color +(or colors) can be specified for "output" pseudocolor, in which case, only +those colors will be affected. For frame look-up tables, +the frame must be specified. + +Two mappings are provided. One uses a set of randomly selected colors +mapped to a specified number of pixel value ranges. The other uses +triangle color mappings. The former is invoked with the \fI(rn sn)\fR +options. In this case, the number following \fBr\fR gives the number of +ranges/levels into which the input data range is to be divided; to +each such range, a randomly selected color is assigned. The number +following \fBs\fR is a seed for the random number generator; changing +this while using the same number of levels gives different color mappings. +The default seed is the number of levels. If only the seed is given (\fBr\fR +omitted), the default number of levels is 8. This mapping is used when +a contour type display is desired: each color represents an intensity range +whose width is inversely proportional to the number of levels. + +The triangle mapping uses a different triangle in each of the three look-up +tables (either the sets associated with the specified frames, or the output +tables). The initial tables map low intensity to blue, middle values to +green, and high values to red, as shown in the diagram. (The red and blue +triangles are truncated as their centers are on a table boundary.) + +Once invoked, the program then allows the user to adjust the triangle +mapping. In +response to the prompt line, select the color to be changed and move the +trackball: the center of the triangle is given by the \fIx\fR cursor +coordinate and the width by the \fIy\fR coordinate. Narrow functions +(small \fIy\fR) allow one to map colors to a limited range of intensity. +When the mapping is satisfactory, a press of any button "fixes" the +mapping and the user may then either select another color or exit. +Before selecting a color, place the cursor at approximately the default +position for the mapping (or where it was for the last mapping of that +color under the current command); otherwise, the color map will change +suddenly when the color is selected via the trackball buttons. +.le +.ls \fBrange\fR N (C) (N C ...) +This command changes the range function in the specified color pipeline +so that the data is scaled by (divided by) the value \fBN\fR. For the +IIS, useful range values are 1,2,4 and 8; anything else will be changed +to the next lowest legal value. +.le +.ls \fBreset\fR [r i t a] +Various registers and tables are reset with this command. If the \fBr\fR +option is used, the registers are reset. This means that zoom is set to +one, all images are centered, split screen is removed, the range values are +set to one and the offset values are set to zero. Also, the cursor is +turned on and its shape is set. Option \fBi\fR causes all the image and +graphics planes to be erased and turned off. Option \fBt\fR resets all +the look-up tables to their default linear, positive slope, form, and +removes any color mappings by making all the output tables the same, and +all the frame specific tables the same. Option \fBa\fR does \fIall\fR +the above. +.le +.ls \fBsnap\fR (C) +This command creates an \fIIRAF\fR image file whose contents are a +512x512 digital snapshot of the image display screen. If no color +is specified, +or if \fIcm\fR (color monochromatic) is given, +the snapshot is of the \fIblue\fR image, which, if you +have a black and white image, is the same as the red or the green +image. Specifying \fBcg\fR for instance will take a snapshot of the +image that you would get had you specified \fIcg\fR for each frame +turned on by the \fIdi\fR command. Color is of interest only when +the window or pseudo color commands have made the three colors distinguishable. +If the "snapped" image is intended to be fed to the Dicomed film +recorder, a black and white image is all that is usually provided and so +a color snap is probably not appropriate. +In the case of the "no color/monochromatic" snap, the graphics planes are +all added together, while, if a real color is given, only the graphics +planes that have some of that color are included in the image. +The color \fBrgb\fR can be +given, in which case the red, green, and blue images are weighted equally +to produce a single image file. This image does not represent well what +you see, partly because of the equal weight given all colors: some +mapping of eye sensitivity is probably what is required, but it is not +implemented. + +The program operates by first determining zoom, pan, offset, tables, etc, +and, for each quadrant of the split screen, which images planes are active. +Then, for each line of the display, those images are read out from the display's +memory and the transformations done in hardware are duplicated pixel by pixel +in software. The word "active" needs a bit of explanation. Any image plane +whose pixels are contributing to the image is active. No image is active if +it has been turned off (by the \fIdi\fR) command (or if all images were +turned off and the one of interest not subsequently turned back on). If the +image is all zeroes, or if it is not but split screen is active and the +part of the image being displayed is all zeroes, it is not contributing to +the output. However, the snap program cannot tell that an active image is +not contributing anything useful, +and so it dutifully reads out each pixel and adds zeroes to the output. +The moral of this is that frames of no interest should be (turned) off before +snap is called (unless you don't have anything better to do than wait for +computer prompts). When split screen is active, frames are read only for +the quadrants in which they are active. + +The fastest snaps are for single images that are zoomed but not panned +and which are displayed (and snapped) in black and white, or snapped +in a single color. +.le +.ls \fBsplit\fR [c o px,y nx,y] +This command sets the split screen point. Option \fBc\fR is shorthand for +\fIcenter\fR, which is the normal selection. Option \fBo\fR stands for +\fIorigin\fR, and is the split position that corresponds to no split screen. +If you wish to specify the split point in pixels, use the \fBpx,y\fR form, in +which the coordinates are given as integers. If you prefer to specify +the point in NDC (which range from 0 though 1.0), use the \fBnx,y\fR form +in which the coordinates are decimal fractions. + +A peculiarity of the IIS hardware is that if no split screen is desired, +the split point must be moved to the upper left corner of the display, rather +than to the lower left (the \fIIRAF\fR 1,1 position). This means that no +split screen (the \fBo\fR option, or what you get after \fBre r\fR) is really +split screen with only quadrant \fBfour\fR displayed: if you use the \fIdi\fR +command with quadrant specification, only quadrant 4 data will be seen. +.le +.ls \fBtell\fR +This command displays what little it knows about the display status. At +present, all it can say is whether any image plane is being displayed, and +if any are, what is the number of one of them. This rather weak performance +is the result of various design decisions both within \fIcv\fR and the +\fIIRAF\fR display code, and may be improved. +.le +.ls \fBwindow\fR (o) (F C) +This command operates just as the \fIpseudo\fR command, except that it +applies a linear mapping to the output look-up tables (if option \fBo\fR +is used) or to the frame specific tables. The mapping is controlled by +the trackball, with the \fIy\fR cursor coordinate supplying the slope +of the map, and \fIx\fR the offset. If different mappings are given to +each color, a form of pseudo-color is generated. +.le +.ls \fBwrite\fR [F C] text +This command writes the given text into either an image plane (or planes) +or into the specified color graphics bit plane(s). The user is prompted +to place the cursor at the (lower left) corner of the text, which is +then written to the right in roman font. The user is also asked for +a text size (default 1.0). If the text is written into a graphics +plane, and a \fBsnap\fR is requested with no color specification, then +text in any graphics plane will be included in the image. A color snap, +on the other hand, will include graphics text to the extent that the +text is displayed in that color. +Text written into an image plane +will have the same appearance as any "full on" pixel; that is, text +in an image plane is written at maximum intensity, +overwrites the image data, +and is affected by look-up tables, offsets, +and so forth, like any other image pixels. +.le +.ls \fBzoom\fR N (F) +This command zooms the display to the power given by \fBN\fR. For the +IIS, the power must be 1,2,4, or 8; anything else is changed to the next +lower legal value. The model 70 zooms all planes together. The center +of the zoom is determined by the cursor position relative to the first +frame specified (if none, the lowest numbered active one). Once the zoom +has taken place, the \fIpan\fR routine is called for the specified frames. +.le +.ih +SEE ALSO +cvl +.endhelp diff --git a/pkg/images/tv/iis/doc/cv.ms b/pkg/images/tv/iis/doc/cv.ms new file mode 100644 index 00000000..d34ccaa0 --- /dev/null +++ b/pkg/images/tv/iis/doc/cv.ms @@ -0,0 +1,332 @@ +.TL +The "cv" Display Package +.AU +Richard Wolff +.DA +.PP +The \fIcv\fR program is used to control the image display from within +\fIIRAF\fR. It differs from most \fIIRAF\fR programs since it has its +own prompt and its own internal "language". Each of the available commands +is described in the following paragraphs, but first a few comments on the +command structure seem in order. Commands are distinguished by their +first letter, except for a few instances where the second letter is needed. +The rest of the command name can be typed if you wish. Commands often +require specification of frames numbers, colors, quadrants, or numeric +values. In most cases, the order is unimportant, but, zoom, for instance, +does require the zoom power right after the command name. The order given +in the \fIhelp\fR command will always work. +.PP +A frame list is indicated in the \fIhelp\fR listing with an \fBF\fR. This +is to be replaced in the typed command by an \fBf\fR followed (no spaces) +with a list of the pertinent image planes. Thus, \fBf1\fR means +.I "frame 1" +while \fBf42\fR means +.I "frames 4" +and \fI2\fR. In most cases, the leading \fBf\fR can be omitted. +The specification \fBfa\fR means \fIall frames\fR. In those +cases in the \fIhelp\fR menu where the frame specification is optional, +omitting the frame list is the same as typing \fBfa\fR; that is, operate +on \fIall\fR frames. +.PP +A color specification is a \fBc\fR followed by a set of letters. +The letter \fBa\fR means \fIall\fR, just as in the frame specification. +The letters \fBr, b,\fR and \fBg\fR are the other possibilities for all +commands other than \fIdg\fR and \fIsnap\fR. For displaying graphics +planes (\fBdg\fR), the other possibilities are \fBy, p, m, w\fR which +stand for \fIyellow, purple, mauve,\fR and \fIwhite\fR. (\fIMauve\fR is +the wrong name and will get changed.) The \fIsnap\fR command accepts, in +addition to the standard three colors, \fBm, bw,\fR and \fBrgb\fR, which +stand for \fImonochrome, black and white,\fR and \fIfull color\fR. (See +the discussion under \fIsnap\fR for further explanation.) +An omitted color specification is the same as \fIall colors\fR. +.PP +Quadrants are given by a \fBq\fR followed by numbers from the set one through +four, or the letter \fBa\fR as in the frame and color cases. Quadrants are +numbered in the standard way, with the upper right being \fI1\fR, the upper +left \fI2\fR, etc. Adjacent quadrants may be referenced by \fBt, b, l,\fR +and \fBr\fR, standing for \fItop, bottom, left,\fR and \fIright\fR. An +omitted quadrant specification is the same as \fIall quadrants\fR. Quadrants +are effective only if the split screen command has set the split point to +something other than the "origin". +.sp +.SH +\fBblink\fR N F (C Q) (F C Q) +.IP +The blink rate is given by \fBN\fR, which is in tenths of a second. Although +current timing routines in \fIIRAF\fR do not recognize partial seconds, +for the NOAO 4.2BSD UNIX implementation, a non-portable timing routine is +used so that tenth seconds are usable. +Erratic timing is pretty much the rule when the system load is large. +One frame must be given, +followed by any color or quadrant specification, and then +optionally followed by any number of similar triads. A specification of +\fI10 f12 f3 f3 f4\fR would display frames one and two for one second, then +frame three for two one second intervals, then frame 4, and then recycle. +The first blink cycle may appear somewhat odd as the code "settles in", +but the sequence should become regular after that (except for timing +problems due to system load). In split screen mode, it is necessary to +specify all the frames together with quadrants, which leads to a lot of +typing: The reason is that blink simply cycles through a series of +\fBdi\fR commands, and hence it requires the same information as that +command. +.SH +\fBcursor\fR [on off F] +.IP +This command is used to turn the cursor on or off, and to read coordinates +and pixel values from a frame. Pixel coordinates for a feature are those +of the image as loaded into the display, and do not change as the image +is panned or zoomed. Fractional pixel positions are given for zoomed +images, with a minimum number of decimal places printed (but the same number +for both the \fIx\fR and \fIy\fR coordinates). +For an unpanned, unzoomed image plane, the lower left corner +of the \fIscreen\fR is (1,1) +even if the image you loaded is smaller than 512x512, occupies only +a portion of the display screen, and does not extend to the lower left +corner of the screen. This defect will likely be remedied +when the \fIcv\fR package is properly integrated into \fIIRAF\fR. +Pixel information can be read from a frame that is not being displayed. +.SH +\fBdi\fR F (C Q) [on off] +.IP +The \fId\fRisplay \fIi\fRmage command turns specified frames on (or off). +Turning a frame off does not erase it. A frame need not have all colors +turned on, nor appear in all quadrants of a split screen display. +.SH +\fBdg\fR C (F Q) [on off] +.IP +The \fId\fRisplay \fIg\fRraphics command turns specific graphics planes +on or off. For the IIS display, neither the frame nor the quadrant +parameters are relevant. A side-effect of this command is that it +resets the graphics hardware to the \fIcv\fR standard: red cursor and +seven graphics planes, each colored differently. If the display is in +a "weird" state that is not cured with the \fIreset r/t\fR commands, +and a \fIreset i\fR would destroy images of interest, try a \fIdg ca on\fR +command followed by \fIdg ca off\fR. +.SH +\fBerase\fR [F all graphics] +.IP +This command erases the specified frame, or all the graphics planes, or +all data planes. The command \fBclear\fR is a synonym. +.SH +\fBmatch\fR (o) (F) (C) (to) (F) (C) +.IP +This command allows the user to copy a look-up table to a specified set +of tables, and hence, to match the mapping function of frames (and/or +colors) to a reference table. If the \fBo\fR parameter is omitted, the +match is among the look-up tables associated with particular frames; +otherwise, the \fIouput\fR tables are used (hence, the \fBo\fR). In the +latter case, only colors are important; the frame information should +be omitted. For the individual frame tables, colors can be omitted, in +which case a match of frame one to two means to copy the three tables +of frame two (red, green, and blue) to those of frame one. Only one +reference frame or color should be given, but \fImatch f23 cgb f1 cr\fR +is legal and means to match the green and blue color tables of both +frames two and three to the red table of frame one. +.SH +\fBoffset\fR C N +.IP +The value N, which can range from -4095 to +4095 is added to the data +pipeline for color \fBC\fR, thus offsetting the data. This is useful +if one needs to change the data range that is mapped into the useful part +of the output tables. +.SH +\fBpan\fR (F) +.IP +When invoked, this command connects the trackball to the specified frames +and allows the user to move (pan/roam/scroll) the image about the screen. +This function is automatically invoked whenever the zoom factor is changed. +.SH +\fBpseudo\fR (o) (F C) (rn sn) +.IP +Look-up tables are changed with the \fIwindow\fR and the \fIpseudocolor\fR +commands. Windowing provides linear functions and is discussed under that +command; \fIpseudo\fR provides pseudo-coloring capabilities. Pseudo-color +maps are usually best done in the output tables, rather than in the +look-up tables associated with particular frames; hence, \fBps o\fR is +the more likely invocation of the start of the command line. A color +(or colors) can be specified for "output" pseudocolor, in which case, only +those colors will be affected. For frame look-up tables, +the frame must be specified. +.IP +Two mappings are provided. One uses a set of randomly selected colors +mapped to a specified number of pixel value ranges. The other uses +triangle color mappings. The former is invoked with the \fI(rn sn)\fR +options. In this case, the number following \fBr\fR gives the number of +ranges/levels into which the input data range is to be divided; to +each such range, a randomly selected color is assigned. The number +following \fBs\fR is a seed for the random number generator; changing +this while using the same number of levels gives different color mappings. +The default seed is the number of levels. If only the seed is given (\fBr\fR +omitted), the default number of levels is 8. This mapping is used when +a contour type display is desired: each color represents an intensity range +whose width is inversely proportional to the number of levels. +.IP +The triangle mapping uses a different triangle in each of the three look-up +tables (either the sets associated with the specified frames, or the output +tables). The initial tables map low intensity to blue, middle values to +green, and high values to red, as shown in the diagram. (The red and blue +triangles are truncated as their centers are on a table boundary.) +.sp +.KS +.PS +B: box +move +G: box +move +R: box +move to B.sw left 0.375 +line dotted to B.nw +line dashed to B.s +move to G.sw +line dashed to G.n +line dashed to G.se +move to R.s +line dashed to R.ne +line dotted to R.se right 0.375 +"blue" at B.s below +"green" at G.s below +"red" at R.s below +.PE +.sp +.KE +.IP +Once invoked, the program then allows the user to adjust the triangle +mapping. In +response to the prompt line, select the color to be changed and move the +trackball: the center of the triangle is given by the \fIx\fR cursor +coordinate and the width by the \fIy\fR coordinate. Narrow functions +(small \fIy\fR) allow one to map colors to a limited range of intensity. +When the mapping is satisfactory, a press of any button "fixes" the +mapping and the user may then either select another color or exit. +Before selecting a color, place the cursor at approximately the default +position for the mapping (or where it was for the last mapping of that +color under the current command); otherwise, the color map will change +suddenly when the color is selected via the trackball buttons. +.SH +\fBrange\fR N (C) (N C ...) +.IP +This command changes the range function in the specified color pipeline +so that the data is scaled by (divided by) the value \fBN\fR. For the +IIS, useful range values are 1,2,4 and 8; anything else will be changed +to the next lowest legal value. +.SH +\fBreset\fR [r i t a] +.IP +Various registers and tables are reset with this command. If the \fBr\fR +option is used, the registers are reset. This means that zoom is set to +one, all images are centered, split screen is removed, the range values are +set to one and the offset values are set to zero. Also, the cursor is +turned on and its shape is set. Option \fBi\fR causes all the image and +graphics planes to be erased and turned off. Option \fBt\fR resets all +the look-up tables to their default linear, positive slope, form, and +removes any color mappings by making all the output tables the same, and +all the frame specific tables the same. Option \fBa\fR does \fIall\fR +the above. +.SH +\fBsnap\fR (C) +.IP +This command creates an \fIIRAF\fR image file whose contents are a +512x512 digital snapshot of the image display screen. If no color +is specified, +or if \fIcm\fR (color monochromatic) is given, +the snapshot is of the \fIblue\fR image, which, if you +have a black and white image, is the same as the red or the green +image. Specifying \fBcg\fR for instance will take a snapshot of the +image that you would get had you specified \fIcg\fR for each frame +turned on by the \fIdi\fR command. Color is of interest only when +the window or pseudo color commands have made the three colors distinguishable. +If the "snapped" image is intended to be fed to the Dicomed film +recorder, a black and white image is all that is usually provided and so +a color snap is probably not appropriate. +In the case of the "no color/monochromatic" snap, the graphics planes are +all added together, while, if a real color is given, only the graphics +planes that have some of that color are included in the image. +The color \fBrgb\fR can be +given, in which case the red, green, and blue images are weighted equally +to produce a single image file. This image does not represent well what +you see, partly because of the equal weight given all colors: some +mapping of eye sensitivity is probably what is required, but it is not +implemented. +.IP +The program operates by first determining zoom, pan, offset, tables, etc, +and, for each quadrant of the split screen, which images planes are active. +Then, for each line of the display, those images are read out from the display's +memory and the transformations done in hardware are duplicated pixel by pixel +in software. The word "active" needs a bit of explanation. Any image plane +whose pixels are contributing to the image is active. No image is active if +it has been turned off (by the \fIdi\fR) command (or if all images were +turned off and the one of interest not subsequently turned back on). If the +image is all zeroes, or if it is not but split screen is active and the +part of the image being displayed is all zeroes, it is not contributing to +the output. However, the snap program cannot tell that an active image is +not contributing anything useful, +and so it dutifully reads out each pixel and adds zeroes to the output. +The moral of this is that frames of no interest should be (turned) off before +snap is called (unless you don't have anything better to do than wait for +computer prompts). When split screen is active, frames are read only for +the quadrants in which they are active. +.IP +The fastest snaps are for single images that are zoomed but not panned +and which are displayed (and snapped) in black and white, or snapped +in a single color. +.SH +\fBsplit\fR [c o px,y nx,y] +.IP +This command sets the split screen point. Option \fBc\fR is shorthand for +\fIcenter\fR, which is the normal selection. Option \fBo\fR stands for +\fIorigin\fR, and is the split position that corresponds to no split screen. +If you wish to specify the split point in pixels, use the \fBpx,y\fR form, in +which the coordinates are given as integers. If you prefer to specify +the point in NDC (which range from 0 though 1.0), use the \fBnx,y\fR form +in which the coordinates are decimal fractions. +.IP +A peculiarity of the IIS hardware is that if no split screen is desired, +the split point must be moved to the upper left corner of the display, rather +than to the lower left (the \fIIRAF\fR 1,1 position). This means that no +split screen (the \fBo\fR option, or what you get after \fBre r\fR) is really +split screen with only quadrant \fBfour\fR displayed: if you use the \fIdi\fR +command with quadrant specification, only quadrant 4 data will be seen. +.SH +\fBtell\fR +.IP +This command displays what little it knows about the display status. At +present, all it can say is whether any image plane is being displayed, and +if any are, what is the number of one of them. This rather weak performance +is the result of various design decisions both within \fIcv\fR and the +\fIIRAF\fR display code, and may be improved. +.SH +\fBwindow\fR (o) (F C) +.IP +This command operates just as the \fIpseudo\fR command, except that it +applies a linear mapping to the output look-up tables (if option \fBo\fR +is used) or to the frame specific tables. The mapping is controlled by +the trackball, with the \fIy\fR cursor coordinate supplying the slope +of the map, and \fIx\fR the offset. If different mappings are given to +each color, a form of pseudo-color is generated. +.SH +\fBwrite\fR [F C] text +.IP +This command writes the given text into either an image plane (or planes) +or into the specified color graphics bit plane(s). The user is prompted +to place the cursor at the (lower left) corner of the text, which is +then written to the right in roman font. The user is also asked for +a text size (default 1.0). If the text is written into a graphics +plane, and a \fBsnap\fR is requested with no color specification, then +text in any graphics plane will be included in the image. A color snap, +on the other hand, will include graphics text to the extent that the +text is displayed in that color. +Text written into an image plane +will have the same appearance as any "full on" pixel; that is, text +in an image plane is written at maximum intensity, +overwrites the image data, +and is affected by look-up tables, offsets, +and so forth, like any other image pixels. +.SH +\fBzoom\fR N (F) +.IP +This command zooms the display to the power given by \fBN\fR. For the +IIS, the power must be 1,2,4, or 8; anything else is changed to the next +lower legal value. The model 70 zooms all planes together. The center +of the zoom is determined by the cursor position relative to the first +frame specified (if none, the lowest numbered active one). Once the zoom +has taken place, the \fIpan\fR routine is called for the specified frames. diff --git a/pkg/images/tv/iis/doc/cvl.hlp b/pkg/images/tv/iis/doc/cvl.hlp new file mode 100644 index 00000000..cda07b07 --- /dev/null +++ b/pkg/images/tv/iis/doc/cvl.hlp @@ -0,0 +1,287 @@ +.help cvl Jul87 images.tv.iis +.ih +NAME +cvl -- load images in image display +.ih +USAGE +cvl image frame +.ih +PARAMETERS +.ls image +Image to be loaded. +.le +.ls frame +Display frame to be loaded. +.le +.ls erase = yes +Erase frame before loading image? +.le +.ls border_erase = no +Erase unfilled area of window in display frame if the whole frame is not +erased? +.le +.ls select_frame = yes +Display the frame to be loaded? +.le +.ls fill = no +Interpolate or block average the image to fit the display window? +.le +.ls zscale = yes +Apply an automatic intensity mapping algorithm when loading the image? +.le +.ls contrast = 0.25 +Contrast factor for the automatic intensity mapping algorithm. +.le +.ls zrange = yes +If not using the automatic mapping algorithm (\fIzscale = no\fR) map the +full range of the image intensity to the full range of the display? +.le +.ls nsample_lines = 5 +Number of sample lines to use in the automatic intensity mapping algorithm. +.le +.ls xcenter = 0.5, ycenter = 0.5 +Horizontal and vertical centers of the display window in normalized +coordinates measured from the left and bottom respectively. +.le +.ls xsize = 1, ysize = 1 +Horizontal and vertical sizes of the display window in normalized coordinates. +.le +.ls xmag = 1., ymag = 1. +Horizontal and vertical image magnifications when not filling the display +window. Magnifications greater than 1 map image pixels into more than 1 +display pixel and magnifications less than 1 map more than 1 image pixel +into a display pixel. +.le +.ls z1, z2 +Minimum and maximum image intensity to be mapped to the minimum and maximum +display levels. These values apply when not using the automatic or range +intensity mapping methods. +.le +.ls ztrans = "linear" +Transformation of the image intensity levels to the display levels. The +choices are: +.ls "linear" +Map the minimum and maximum image intensities linearly to the minimum and +maximum display levels. +.le +.ls "log" +Map the minimum and maximum image intensities linearly to the range 1 to 1000, +take the logarithm (base 10), and then map the logarithms to the display +range. +.le +.ls "none" +Apply no mapping of the image intensities (regardless of the values of +\fIzscale, zrange, z1, and z2\fR). For most image displays, values exceeding +the maximum display value are truncated by masking the highest bits. +This corresponds to applying a modulus operation to the intensity values +and produces "wrap-around" in the display levels. +.le +.ls "user" +User supplies a look up table of intensities and their corresponding +greyscale values. +.le +.le +.ls lutfile = "" +Name of text file containing the look up table when \fIztrans\fR = user. +The table should contain two columns per line; column 1 contains the +intensity, column 2 the desired greyscale output. +.le +.ih +DESCRIPTION +The specified image is loaded into the specified frame of the standard +image display device ("stdimage"). For devices with more than one +frame it is possible to load an image in a frame different than that +displayed on the monitor. An option allows the loaded frame to become +the displayed frame. The previous contents of the frame may be erased +(which can be done very quickly on most display devices) before the +image is loaded. Without erasing, the image replaces only those pixels +in the frame defined by the display window and spatial mapping +described below. This allows displaying more than one image in a +frame. An alternate erase option erases only those pixels in the +defined display window which are not occupied by the image being +loaded. This is generally slower than erasing the entire frame and +should be used only if a display window is smaller than the entire +frame. + +The image is mapped both in intensity and in space. The intensity is +mapped from the image pixel values to the range of display values in +the device. Spatial interpolation maps the image pixel coordinates +into a part of the display frame called the display window. Many of +the parameters of this task are related to these two transformations. + +A display window is defined in terms of the full frame. The lower left +corner of the frame is (0, 0) and the upper right corner is (1, 1) as viewed on +the monitor. The display window is specified by a center (defaulted to the +center of the frame (0.5, 0.5)) and a size (defaulted to the full size of +the frame, 1 by 1). The image is loaded only within the display window and +does not affect data outside the window; though, of course, an initial +frame erase erases the entire frame. By using different windows one may +load several images in various parts of the display frame. + +If the option \fIfill\fR is selected the image is spatially interpolated +to fill the display window in its largest dimension (with an aspect +ratio of 1:1). When the display window is not automatically filled +the image is scaled by the magnification factors (which need not be +the same) and centered in the display window. If the number of image +pixels exceeds the number of display pixels in the window only the central +portion of the image which fills the window is loaded. By default +the display window is the full frame, the image is not interpolated +(no filling and magnification factors of 1), and is centered in the frame. +The spatial interpolation algorithm is described in the section +MAGNIFY AND FILL ALGORITHM. + +There are several options for mapping the pixel values to the display +values. There are two steps; mapping a range of image intensities to +the full display range and selecting the mapping function or +transformation. The mapping transformation is set by the parameter +\fIztrans\fR. The most direct mapping is "none" which loads the image +pixel values directly without any transformation or range mapping. +Most displays only use the lowest bits resulting in a wrap-around +effect for images with a range exceeding the display range. This is +sometimes desirable because it produces a contoured image which is not +saturated at the brightest or weakest points. This transformation is +also the fastest. Another transformation, "linear", maps the selected +image range linearly to the full display range. The logarithmic +transformation, "log", maps the image range linearly between 1 and 1000 +and then maps the logarithm (base 10) linearly to the full display +range. In the latter transformations pixel values greater than +selected maximum display intensity are set to the maximum display value +and pixel values less than the minimum intensity are set to the minimum +display value. + +Methods for setting of the range of image pixel values, \fIz1\fR and +\fIz2\fR, to be mapped to the full display range are arranged in a +hierarchy from an automatic mapping which gives generally good result +for typical astronomical images to those requiring the user to specify +the mapping in detail. The automatic mapping is selected with the +parameter \fIzscale\fR. The automatic mapping algorithm is described +in the section ZSCALE ALGORITHM and has two parameters, +\fInsample_lines\fR and \fIcontrast\fR. + +When \fIztrans\fR = user, a look up table of intensity values and their +corresponding greyscale levels is read from the file specified by the +\fIlutfile\fR parameter. From this information, a piecewise linear +look up table containing 4096 discrete values is composed. The text +format table contains two columns per line; column 1 contains the +intensity, column 2 the desired greyscale output. The greyscale values +specified by the user must match those available on the output device. +Task \fIshowcap\fR can be used to determine the range of acceptable +greyscale levels. When \fIztrans\fR = user, parameters \fIzscale\fR, +\fIzrange\fR and \fIzmap\fR are ignored. + +If the zscale algorithm is not selected the \fIzrange\fR parameter is +examined. If \fIzrange\fR is yes then \fIz1\fR and \fIz2\fR are set to +the minimum and maximum image pixels values, respectively. This insures +that the full range of the image is displayed but is generally slower +than the zscale algorithm (because all the image pixels must be examined) +and, for images with a large dynamic range, will generally show only the +brightest parts of the image. + +Finally, if the zrange algorithm is not selected the user specifies the +values of \fIz1\fR and \fIz2\fR directly. +.ih +ZSCALE ALGORITHM +The zscale algorithm is designed to display the image values near the median +image value without the time consuming process of computing a full image +histogram. This is particularly useful for astronomical images which +generally have a very peaked histogram corresponding to the background +sky in direct imaging or the continuum in a two dimensional spectrum. + +A subset of the image is examined. Approximately 600 pixels are +sampled evenly over the image. The number of lines is a user parameter, +\fInsample_lines\fR. The pixels are ranked in brightness to +form the function I(i) where i is the rank of the pixel and I is its value. +Generally the midpoint of this function (the median) is very near the peak +of the image histogram and there is a well defined slope about the midpoint +which is related to the width of the histogram. At the ends of the +I(i) function there are a few very bright and dark pixels due to objects +and defects in the field. To determine the slope a linear function is fit +with iterative rejection; + + I(i) = intercept + slope * (i - midpoint) + +If more than half of the points are rejected +then there is no well defined slope and the full range of the sample +defines \fIz1\fR and \fIz2\fR. Otherwise the endpoints of the linear +function are used (provided they are within the original range of the +sample): + +.nf + z1 = I(midpoint) + (slope / contrast) * (1 - midpoint) + z2 = I(midpoint) + (slope / contrast) * (npoints - midpoint) +.fi + +As can be seen, the parameter \fIcontrast\fR may be used to adjust the contrast +produced by this algorithm. +.ih +MAGNIFY AND FILL ALGORITHM +The spatial interpolation algorithm magnifies (or demagnifies) the +image along each axis by the desired amount. The fill option is a +special case of magnification in that the magnification factors are set +by the requirement that the image just fit the display window in its +maximum dimension with an aspect ratio (ratio of magnifications) of 1. +There are two requirements on the interpolation algorithm; all the +image pixels must contribute to the interpolated image and the +interpolation must be time efficient. The second requirement means that +simple linear interpolation is used. If more complex interpolation is +desired then tasks in the IMAGES package must be used to first +interpolate the image to the desired size before loading the display +frame. + +If the magnification factors are greater than 0.5 (sampling step size +less than 2) then the image is simply interpolated. However, if the +magnification factors are less than 0.5 (sampling step size greater +than 2) the image is first block averaged by the smallest amount such +that magnification in the reduced image is again greater than 0.5. +Then the reduced image is interpolated to achieve the desired +magnifications. The reason for block averaging rather than simply +interpolating with a step size greater than 2 is the requirement that +all of the image pixels contribute to the displayed image. If this is +not desired then the user can explicitly subsample using image +sections. The effective difference is that with subsampling the +pixel-to-pixel noise is unchanged and small features may be lost due to +the subsampling. With block averaging pixel-to-pixel noise is reduced +and small scale features still contribute to the displayed image. +.ih +EXAMPLES +For the purpose of these examples we assume a display with four frames, +512 x 512 in size, and a display range of 0 to 255. Also consider two +images, image1 is 100 x 200 with a range 200 to 2000 and image2 is +2000 x 1000 with a range -1000 to 1000. To load the images with the +default parameters: + +.nf + cl> cvl image1 1 + cl> cvl image2 2 +.fi + +The image frames are first erased and image1 is loaded in the center of +display frame 1 without spatial interpolation and with the automatic intensity +mapping. Only the central 512x512 area of image2 is loaded in display frame 2 + +To load the display without any intensity transformation: + + cl> cvl image1 1 ztrans=none + +The next example interpolates image2 to fill the full 512 horizontal range +of the frame and maps the full image range into the display range. Note +that the spatial interpolation first block averages by a factor of 2 and then +magnifies by 0.512. + + cl> cvl image2 3 fill+ zscale- + +The next example makes image1 square and sets the intensity range explicitly. + + cl> cvl image1 4 zscale- zrange- z1=800 z2=1200 xmag=2 + +The next example loads the two images in the same frame side-by-side. + +.nf + cl> cvl.xsize=0.5 + cl> cvl image1 fill+ xcen=0.25 + cl> cvl image2 erase- fill+ xcen=0.75 +.fi +.ih +SEE ALSO +display, magnify +.endhelp diff --git a/pkg/images/tv/iis/doc/erase.hlp b/pkg/images/tv/iis/doc/erase.hlp new file mode 100644 index 00000000..6a3548e6 --- /dev/null +++ b/pkg/images/tv/iis/doc/erase.hlp @@ -0,0 +1,26 @@ +.help erase Jan86 images.tv.iis +.ih +NAME +erase -- erase display frame +.ih +USAGE +erase frame +.ih +PARAMETERS +.ls frame +Frame to be erased. +.le +.ih +DESCRIPTION +The specified frame in the image display ("stdimage") is erased. +Note that the erased frame can be different than the frame currently +being displayed on the monitor. The graphics frame is not erased. +.ih +EXAMPLES +To erase frame 3: + + cl> erase 3 +.ih +SEE ALSO +cv +.endhelp diff --git a/pkg/images/tv/iis/doc/frame.hlp b/pkg/images/tv/iis/doc/frame.hlp new file mode 100644 index 00000000..ec3a9059 --- /dev/null +++ b/pkg/images/tv/iis/doc/frame.hlp @@ -0,0 +1,24 @@ +.help frame Jan86 images.tv.iis +.ih +NAME +frame -- select frame to be displayed on the image display +.ih +USAGE +frame frame +.ih +PARAMETERS +.ls frame +Frame to be displayed. +.le +.ih +DESCRIPTION +The specified frame is displayed on the image display monitor ("stdimage"). +.ih +EXAMPLES +To display frame 3: + + cl> frame 3 +.ih +SEE ALSO +cv +.endhelp diff --git a/pkg/images/tv/iis/doc/lumatch.hlp b/pkg/images/tv/iis/doc/lumatch.hlp new file mode 100644 index 00000000..95e6f800 --- /dev/null +++ b/pkg/images/tv/iis/doc/lumatch.hlp @@ -0,0 +1,28 @@ +.help lumatch Jan86 images.tv.iis +.ih +NAME +lumatch -- match lookup tables for two display frames +.ih +USAGE +lumatch frame ref_frame +.ih +PARAMETERS +.ls frame +Frame whose lookup table is to be adjusted. +.le +.ls ref_frame +Frame whose lookup table is to be matched. +.le +.ih +DESCRIPTION +The lookup tables mapping the display frame values to the grey levels +on the display monitor are matched in one frame to a reference frame. +.ih +EXAMPLES +To match the lookup tables in frame 3 to those in frame 1: + + cl> lumatch 3 1 +.ih +SEE ALSO +cv +.endhelp diff --git a/pkg/images/tv/iis/doc/monochrome.hlp b/pkg/images/tv/iis/doc/monochrome.hlp new file mode 100644 index 00000000..70cc7aee --- /dev/null +++ b/pkg/images/tv/iis/doc/monochrome.hlp @@ -0,0 +1,18 @@ +.help monochrome Jan86 images.tv.iis +.ih +NAME +monochrome -- select monochrome enhancement +.ih +USAGE +monochrome +.ih +DESCRIPTION +Set the display monitor to display monochrome grey levels by setting +the lookup tables for each color gun to the same values. +.ih +EXAMPLES + cl> monochrome +.ih +SEE ALSO +cv +.endhelp diff --git a/pkg/images/tv/iis/doc/pseudocolor.hlp b/pkg/images/tv/iis/doc/pseudocolor.hlp new file mode 100644 index 00000000..1c7bb70a --- /dev/null +++ b/pkg/images/tv/iis/doc/pseudocolor.hlp @@ -0,0 +1,41 @@ +.help pseudocolor Jan86 images.tv.iis +.ih +NAME +pseudocolor -- select pseudocolor enhancement +.ih +USAGE +pseudocolor +.ih +PARAMETERS +.ls enhancement +Type of pseudocolor enhancement. The types are: +.ls "random" +A randomly chosen color is assigned to each display level. +.le +.ls "linear" +The display levels are mapped into a spectrum. +.le +.ls "8color" +Eight colors are chosen at random over the range of the display levels. +.le +.le +.ls window = yes +Window the lookup table for the frame after enabling the pseudocolor? +.le +.ih +DESCRIPTION +The display levels from the lookup table are mapped into various saturated +colors to enhance an image. There is a choice of three color mappings. +After the pseudocolor enhancement is enabled on the display monitor the +user may, optionally, adjust the frame lookup table. +.ih +EXAMPLES +.nf + cl> pseudocolor random + cl> pseudocolor 8color + cl> pseudocolor linear +.fi +.ih +SEE ALSO +cv +.endhelp diff --git a/pkg/images/tv/iis/doc/rgb.hlp b/pkg/images/tv/iis/doc/rgb.hlp new file mode 100644 index 00000000..1bd9aa13 --- /dev/null +++ b/pkg/images/tv/iis/doc/rgb.hlp @@ -0,0 +1,33 @@ +.help rgb Jan86 images.tv.iis +.ih +NAME +rgb - select true color mode (red, green, and blue frames) +.ih +USAGE +rgb red_frame green_frame blue_frame +.ih +PARAMETERS +.ls red_frame +Frame to use for the red component. +.le +.ls green_frame +Frame to use for the green component. +.le +.ls blue_frame +Frame to use for the blue component. +.le +.ls window = no +Window the rgb lookup tables? +.le +.ih +DESCRIPTION +Set the display monitor to display rgb colors by using three frames to +drive the red, green, and blue guns of the color display monitor. +Optionally, window the rgb lookup tables. +.ih +EXAMPLES + cl> rgb 1 2 3 +.ih +SEE ALSO +cv +.endhelp diff --git a/pkg/images/tv/iis/doc/window.hlp b/pkg/images/tv/iis/doc/window.hlp new file mode 100644 index 00000000..f98130c3 --- /dev/null +++ b/pkg/images/tv/iis/doc/window.hlp @@ -0,0 +1,38 @@ +.help window Jan86 images.tv.iis +.ih +NAME +window -- adjust the contrast and dc offset of the current frame +.ih +USAGE +window +.ih +DESCRIPTION +The lookup table between the display frame values and the values sent +to the display monitor is adjusted interactively to enhance the display. +The mapping is linear with two adjustable parameters; the intercept +and the slope. The two values are set with the image display cursor +in the two dimensional plane of the display. The horizontal position +of the cursor sets the intercept or zero point of the transformation. +Moving the cursor to the left lowers the zero point while moving the cursor to +the right increases the zero point. The vertical position of the cursor +sets the slope of the transformation. The middle of the display is zero +slope (all frame values map into the same output value) while points above +the middle have negative slope and points below the middle have positive +slope. Positions near the middle have low contrast while positions near +the top and bottom have very high contrast. By changing the slope from +positive to negative the image may be displayed as positive or negative. + +The interactive loop is exited by pressing any button on the cursor control. +.ih +EXAMPLES +.nf + cl> window + Window the display and push any button to exit: +.fi +.ih +BUGS +It may be necessary to execute FRAME before windowing. +.ih +SEE ALSO +cv +.endhelp diff --git a/pkg/images/tv/iis/doc/zoom.hlp b/pkg/images/tv/iis/doc/zoom.hlp new file mode 100644 index 00000000..85a0b604 --- /dev/null +++ b/pkg/images/tv/iis/doc/zoom.hlp @@ -0,0 +1,31 @@ +.help zoom Jan86 images.tv.iis +.ih +NAME +zoom - zoom in on the image (change magnification) +.ih +USAGE +zoom +.ls zoom_factor +Zoom factor by the display is to be expanded. The factors are powers +of 2; 1 = no zoom, 2 = factor of 2, 3 = factor of 4, and 4 = factor of 8. +.le +.ls window = no +Window the enlarged image? +.le +.ih +DESCRIPTION +The display is zoomed by the specified factor. A zoom factor of 1 is no +magnification and higher factors correspond to factors of 2. The zoom +replicates pixels on the monitor and only a part of the display frame +centered on the display cursor is visible. The window option allows +the user to adjust interactively with the cursor the part of the zoomed +frame. +.ih +EXAMPLES +To magnify the displayed frame by a factor of 2: + + cl> zoom 2 +.ih +SEE ALSO +cv +.endhelp diff --git a/pkg/images/tv/iis/erase.cl b/pkg/images/tv/iis/erase.cl new file mode 100644 index 00000000..4da666bc --- /dev/null +++ b/pkg/images/tv/iis/erase.cl @@ -0,0 +1,10 @@ +#{ ERASE -- Erase a greyscale display frame. + +# frame,i,a,1,1,4,frame to be erased +# saveframe,i,h + +{ + saveframe = _dcontrol.frame + _dcontrol (frame=frame, erase=yes) + _dcontrol (frame = saveframe) +} diff --git a/pkg/images/tv/iis/erase.par b/pkg/images/tv/iis/erase.par new file mode 100644 index 00000000..0f84180f --- /dev/null +++ b/pkg/images/tv/iis/erase.par @@ -0,0 +1,2 @@ +frame,i,a,1,1,4,frame to be erased +saveframe,i,h diff --git a/pkg/images/tv/iis/frame.cl b/pkg/images/tv/iis/frame.cl new file mode 100644 index 00000000..1252f7da --- /dev/null +++ b/pkg/images/tv/iis/frame.cl @@ -0,0 +1,5 @@ +#{ FRAME -- Select the frame to be displayed. + +{ + _dcontrol (type="frame", frame=frame) +} diff --git a/pkg/images/tv/iis/giis.par b/pkg/images/tv/iis/giis.par new file mode 100644 index 00000000..5e000c89 --- /dev/null +++ b/pkg/images/tv/iis/giis.par @@ -0,0 +1,7 @@ +input,s,a,,,,input metacode file +device,s,h,"stdimage",,,output device +generic,b,h,no,,,ignore remaining kernel dependent parameters +debug,b,h,no,,,print decoded graphics instructions during processing +verbose,b,h,no,,,"print elements of polylines, cell arrays, etc. in debug mode" +gkiunits,b,h,no,,,print coordinates in GKI rather than NDC units +txquality,s,h,"normal","normal|low|medium|high",,character generator quality diff --git a/pkg/images/tv/iis/ids/doc/Imdis.hlp b/pkg/images/tv/iis/ids/doc/Imdis.hlp new file mode 100644 index 00000000..0ddd46e5 --- /dev/null +++ b/pkg/images/tv/iis/ids/doc/Imdis.hlp @@ -0,0 +1,793 @@ +.help imdis Dec84 "Image Display I/O" +.ce +\fBImage display I/O Design\fR +.ce +Richard Wolff +.ce +May 1985 +.sp 1 +.nh +Introduction + + The image display i/o interface uses the features of the GIO interface +to provide for the reading and writing of images and for the control of +the various subunits of a typical image display device. The cell array +calls of GIO are used for the image data, while the text and polyline +functions handle the text and line generation. Cursor reads are also +done with standard GIO calls. However, all the other display functions +are implemented through a series of GIO escape sequences, which are +described in this document. +.sp +.nh +Escape sequences + + Each sequence is described here, giving first a line with the count +of the number of words in the escape "instruction", followed by the data. +Since most of the data items might be more rationally considered arrays, +they are so indicated here. This means that in most cases, the number of +words in the escape instruction cannot be determined until run-time; an +indication of this is the use of "sizeof(arrays)" to indicate the number +of words in all the pseudo arrays. +.sp +Escape 10 -- reset +.ls +.tp 5 +1 hard/medium/soft +.ls +.nf +hard Clear image and graphics planes +medium reset all (lookup) tables to linear +soft reset scroll, zoom, cursor, alu, etc. +.fi +.le +.le +.sp +This sequence is used to preform various reset commands. These are not +done at GKOPENWS time because the user will not necessarily want to +upset the existing display when the image kernel is started up. +.sp +Escape 11 -- set image plane +.ls +.tp 4 +sizeof(arrays) IFA IBPL +.ls +.nf +IFA(i) image frame array +IBPL(i) image bit plane array +.fi +.le +.le +.sp +This sequence is essentially a header to the getcell/putcell calls. It +identifies both the frame(s) and bit plane(s) to be read or written. IFA +is an array of (short) integers, each of which specifies a plane (using +one indexing), the last element of the array being the integer IDS_EOD +to flag the End Of Data. IDS_EOD is a defined to be (-2). IBPL represents +the bit planes that are to be read or written for all the frames in IFA. +The data is IBPL is terminated with IDS_EOD. If the first element of IFA (or +IBPL) is IDS_EOD, all image frames (all bit planes) are involved in the I/O. +All "array" data are expected to be terminated with IDS_EOD, and the general +convention is maintained that IDS_EOD with no preceding data implies all +"frames", "colors", or whatever. +.sp +Escape 12 -- set graphics plane +.ls +.tp 4 +sizeof(arrays) GFA GBPL +.ls +.nf +GFA(i) graphics frame array +GBPL(i) graphics bit plane array +.fi +.le +.le +.sp +This sequence is identical to escape 11, but refers to graphics planes +instead of image planes. Generally, each graphics bit plane will refer to +a particular color, or perhaps, to a particular image plane. But there is +no enforced correspondence between graphics planes and image planes or colors. +The GFA specifies a set of graphics planes, and is probably unnecessary as the +bitplane array carries adequate information. Including it, however, retains +symmetry with escape 11. Thus, GFA cannot be omitted, for otherwise the +kernel would not know where GBPL started, but is set to IDS_EOD, and the +kernel can then find and ignore it. +.sp +Escape 13 -- display image +.ls +.tp 6 +1+sizeof(arrays) ON/OFF IFA ICOLOR IQUAD +.ls +.nf +ON/OFF turn frame on or off +IFA(i) image frame array +ICOLOR(i) image color array +IQUAD(i) image quadrant array (for split screen mode) +.fi +.le +.le +.sp +The specified image planes are all to be displayed in all the colors given +by ICOLOR. If ICOLOR(1) is IDS_EOD, a full color display is implied. +The quadrant value specifies which quadrant the frames are +to appear in--this is needed only when the split screen mode is in effect; +otherwise, IQUAD[1] = IDS_EOD. +.sp +Escape 14 -- display graphics +.ls +.tp 6 +1+sizeof(arrays) ON/OFF GBPL GCOLOR GQUAD +.ls +.nf +ON/OFF turn referenced planes on or off +GBPL(i) graphics bit plane array +GCOLOR(i) graphics color array +GQUAD(i) graphics quadrant array (for split screen mode) +.fi +.le +.le +.sp +This sequence is identical to escape 13, except for the substitution of +a bitplane array for frames, since graphics are usually treated bit by bit. +[With the IIS systems, for instance, this call requires manipulation of +the color-graphics lookup table.] +.sp +Escape 15 -- save device state +.ls +.tp 5 +1+sizeof(arrays) FD IFA GFA +.ls +.nf +FD file descriptor for save file +IFA(i) image frame array +GFA(i) graphics frame array +.fi +.le +.le +.sp +Saves the specified image frames and graphics planes and all the device +dependent status information in the file referenced by FD. Not implemented +in the Kernel (yet). +.sp +Escape 16 -- restore device state +.ls +.tp 5 +1+sizeof(arrays) FD IFA GFA +.ls +.nf +FD file descriptor for restore file +IFA(i) image frame array +GFA(i) graphics frame array +.fi +.le +.le +.sp +Restores the specified image frames and graphics planes and all the device +dependent status information from the file referenced by FD. Not implemented +in the Kernel (yet). +.sp +Escape 17 -- control +.ls +.tp 9 +4+sizeof(arrays) REG RW N FRAME COLOR OFFSET DATA +.ls +.nf +REG(i) control register or function +RW(i) read or write (write is 0, read 1, wait/read is 2) +N(i) Number of data values +FRAME(i) frame array +COLOR(i) color array +OFFSET(i) offset or other datum +DATA(Ni) array of data +.fi +.le +.le +.sp +Escape 18 is a very general sequence for writing any device +control register. Such "registers" include such generally available +capabilities as look-up tables, as well as specifics, such as min/max +registers. The upper level code may have to consult an "imagecap" +file to determine what it can request. + +FRAME, OFFSET, and COLOR, may not be needed for a particular operation, +but these arrays cannot be omitted; rather, use a one element array with +the value IDS_EOD. Should additional information be needed for an operation, +it can be transmitted in DATA. +.sp +.nh +Examples + +.sp +To clear all frames, one would issue the following sequence +.ls +.tp 4 +.nf +GKI_ESCAPE 11 IFA[1] = IDS_EOD IBPL[1] = IDS_EOD +GKI_CLEARWS +GKI_ESCAPE 12 IFA[1] = IDS_EOD IBPL[1] = IDS_EOD +GKI_CLEARWS +.fi +.le +.sp +To write an image to frame 2 ( IIS internal frame number 1 ) +.ls +.tp 2 +.nf +GKI_ESCAPE 11 IFA[1] = 2 IFA[2] = IDS_EOD IBPL[1] = IDS_EOD +GKI_PCELL data +.fi +.le +.sp +To activate frame 1 in red and green +.ls +.tp 2 +.nf +GKI_ESCAPE 13 IFA[1] = 1 IFA[2] = IDS_EOD ICOLOR[1] = IDS_RED + ICOLOR[2] = IDS_GREEN ICOLOR[3] = IDS_EOD + IQUAD[1] = IDS_EOD +.fi +.le +.sp +.bp +.nh +Defines + +This section presents the value and intended use of each of the various +defined constants. This list is likely to expand. + +.nf +define IDS_EOD (-2) # flag for end of data + +define IDS_RESET 10 # escape 10 +define IDS_R_HARD 0 # hard reset +define IDS_R_MEDIUM 1 # medium +define IDS_R_SOFT 2 +define IDS_R_SNAPDONE 3 # end snap + +define IDS_SET_IP 11 # escape 11 +define IDS_SET_GP 12 # escape 12 +define IDS_DISPLAY_I 13 # escape 13 +define IDS_DISPLAY_G 14 # escape 14 +define IDS_SAVE 15 # escape 15 +define IDS_RESTORE 16 # escape 16 + +# max sizes + +define IDS_MAXIMPL 16 # maximum number of image planes +define IDS_MAXGRPL 16 # maximum number of graphics planes +define IDS_MAXBITPL 16 # maximum bit planes per frame +define IDS_MAXGCOLOR 8 # maximum number of colors (graphics) +define IDS_MAXDATA 8192 # maximum data structure in display + +define IDS_RED 1 +define IDS_GREEN 2 +define IDS_BLUE 3 +define IDS_YELLOW 4 +define IDS_RDBL 5 +define IDS_GRBL 6 +define IDS_WHITE 7 +define IDS_BLACK 8 + +define IDS_QUAD_UR 1 # upper right quad.: split screen mode +define IDS_QUAD_UL 2 +define IDS_QUAD_LL 3 +define IDS_QUAD_LR 4 + +define IDS_CONTROL 17 # escape 17 +define IDS_CTRL_LEN 6 +define IDS_CTRL_REG 1 # what to control +define IDS_CTRL_RW 2 # read/write field in control instr. +define IDS_CTRL_N 3 # count of DATA items +define IDS_CTRL_FRAME 4 # pertinent frame(s) +define IDS_CTRL_COLOR 5 # and color +define IDS_CTRL_OFFSET 6 # generalized "register" +define IDS_CTRL_DATA 7 # data array + +define IDS_WRITE 0 # write command +define IDS_READ 1 # read command +define IDS_READ_WT 2 # wait for action, then read +define IDS_OFF 1 # turn whatever off +define IDS_ON 2 +define IDS_CBLINK 3 # cursor blink +define IDS_CSHAPE 4 # cursor shape + +define IDS_CSTEADY 1 # cursor blink - steady (no blink) +define IDS_CFAST 2 # cursor blink - fast +define IDS_CMEDIUM 3 # cursor blink - medium +define IDS_CSLOW 4 # cursor blink - slow + +define IDS_FRAME_LUT 1 # look-up table for image frame +define IDS_GR_MAP 2 # graphics color map...lookup table per + # se makes little sense for bit plane +define IDS_INPUT_LUT 3 # global input lut +define IDS_OUTPUT_LUT 4 # final lut +define IDS_SPLIT 5 # split screen coordinates +define IDS_SCROLL 6 # scroll coordinates +define IDS_ZOOM 7 # zoom magnification +define IDS_OUT_OFFSET 8 # output bias +define IDS_MIN 9 # data minimum +define IDS_MAX 10 # data maximum +define IDS_RANGE 11 # output range select +define IDS_HISTOGRAM 12 # output data histogram +define IDS_ALU_FCN 13 # arithmetic feedback function +define IDS_FEEDBACK 14 # feedback control +define IDS_SLAVE 15 # auxiliary host or slave processor + +define IDS_CURSOR 20 # cursor control - on/off/blink/shape +define IDS_TBALL 21 # trackball control - on/off +define IDS_DIGITIZER 22 # digitizer control - on/off + +define IDS_BLINK 23 # for blink request +define IDS_SNAP 24 # snap function +define IDS_MATCH 25 # match lookup tables + +# snap codes ... just reuse color codes from above. +define IDS_SNAP_RED IDS_RED # snap the blue image +define IDS_SNAP_GREEN IDS_GREEN # green +define IDS_SNAP_BLUE IDS_BLUE # blue +define IDS_SNAP_RGB IDS_BLACK # rgb image --- do all three +define IDS_SNAP_MONO IDS_WHITE # do just one + +# cursor parameters + +define IDS_CSET 128 # number of cursors per "group" + +define IDS_CSPECIAL 4097 # special "cursors" + # must be > (IDS_CSET * number of cursor groups) +define IDS_CRAW IDS_CSPECIAL # raw cursor read +define IDS_BUT_RD 4098 # "cursor number" for read buttons cmd +define IDS_BUT_WT 4099 # wait for button press, then read +define IDS_CRAW2 4100 # a second "raw" cursor +.fi +.nh +Explanation + + Most of the control functions of an image display do not fit within +the standard GIO protocols, which is why the escape function is provided. +However, image displays exhibit a wide range of functionality, and some +balance must be achieved between code portability/device independence and +use of (possibly peculiar) capabilities of a particular device. The control +functions (such as IDS_FRAME_LUT, IDS_CURSOR, IDS_SLAVE) "selected" here +are, for the most part, general functions, but the code was written with +the IIS Model 70 at hand (and in mind), and some "defines" reflect this. + + The model of the display is a device with some number of image frames, +each of which has associated with it an INPUT look-up table, used for +scaling or bit selection as data is written into the image frame; +a FRAME look-up table for each of the three primary colors, used to +alter the video stream from the image frame; combining logic that sums the +output of the various FRAME tables, forming three data streams, one for +each color; an OUTPUT look-up table that forms a final transformation +on each color prior to the data being converted to analog form; and +possibly, bias (OUT_OFFSET) and RANGE scaling applied somewhere in the +data stream (most likely near the OUTPUT look-up tables). + + Each image plane can be SCROLLed and ZOOMed independently (though +of course, not all devices can do this), and there may be SPLIT screen +capability, with the possibility of displaying parts of four images +simultaneously. + + Hooks have been provided in case there is a ALU or FEEDBACK hardware, +or there is a SLAVE processor, but use of these functions is likely to +be quite device dependent. The IIS can return to the user the MINimum +and MAXimum of a color data stream, and can also run a histogram on +selected areas of the display: There are "defines" pointing to these +functions, but their use is not yet specified and there is not yet +a clean way, within the GIO protocols, for reading back such data. + + Three functions that not so hardware oriented have "defines": +BLINK, MATCH and SNAP. The first is used if the hardware supports +blink. MATCH allows the kernel code to copy look-up tables---something +the upper level code could do were there a well defined mechanism for +reading non-image data back. SNAP is used to set-up the kernel so that +a subsequent set of get_cellarray calls can be used to return a data +stream that represents the digital data arriving at the +digital-to-analog converters: the kernel mimics the hardware and so +provides a digital snapshot of the image display screen. + + Images are loaded by a series of put_cellarray calls, preceded +by one IDS_SET_IP escape to configure the kernel to write the put_cell +data into the correct image planes (and optionally, specific bit planes). +The graphics planes are written to in the same manner, except that +IDS_SET_GP is used. It is not guaranteed that the SET_IP and SET_GP +are independent, and so the appropriate one should be given before +each put_cell sequence. Put_cells can be done for any arbitrary +rectangular array; they are turned into a series of writes to a +sequence of image rows by the GIO interface code. + + Calls to put_cell require the mapping of pixel coordinates +to NDC, which is made more complex than one might first +guess by the fact that the cell array operations are specified +by *inclusive* end points...See the write-up in "Note.pixel". + + Images planes are erased by the standard GIO gclear call, which +must be preceded by a SET_IP (or SET_GP for graphics). This is +perceived as reasonably consistent with the image loading as erasure +is loading with zeros, but presumably can be done far more efficiently +in most devices than with a series of put_cell calls. + + Images planes are turned on and off with IDS_DISPLAY_I, and graphics +planes with IDS_DISPLAY_G. Color and quadrant information must be +supplied as mentioned in the descriptions for escapes 13 and 14. + + The look-up tables are specified to the lower level code by giving +the end points of the line segments which describe the table function. +The end points are specified in NDC. This makes for a +simple, and device independent, upper level code. However, there is no +obvious (to the writer at least) code to invert the process, and return +end points for the simplest line segments that would describe a given +look-up table. (Moreover, there is no mechanism to return such information +to the upper level.) Therefore, the kernel code is asymmetric, in that +writes to the tables are fed data in the form of end points, but reads from +the tables (needed for the kernel implementation of SNAP) return the +requested number data values as obtained from the hardware. + + The control sequence for the ZOOM function requires, in addition to +the usual frame/color information, a zoom power followed by the GKI +coordinates of the pixel to be placed at the screen center. Likewise, +the SCROLL and SPLIT screen functions require GKI center coordinates. + + The OFFSET and RANGE sequences provide for bias and scaling of the +image data. Where they take effect is not specified. Offset requires +a signed number to be added to the referenced data; range is specified +by a small integer which selects the "range" of the data. + + Control of hardware cursors, trackballs, etc is provided: CURSOR +can be used to select cursor shape, blink rate, etc. Devices such as +(trackball) buttons are interrogated as if they are cursors, with a +cursor number that is greater than to IDS_CSPECIAL. The "key" value +returned by a "read" call to devices such as the trackball buttons will +be zero if no button was pressed or some positive number to represent +the activated device. Any "read" may be instructed to return +immediately (IDS_READ) or wait for some action (IDS_READ_WT); for +buttons, there are special IDS_BUT_RD/IDS_BUT_WT. + + Cursors are read and written through the standard GIO interface. +The cursor number ranges from 1 up through IDS_CSPECIAL-1. Each +frame has a set of set of cursors associated with it: frame n has +cursors numbered n, IDS_CSET+n, 2*IDS_CSET+n, etc. Currently, +IDS_CSPECIAL is 4097, and IDS_CSET is 128, so there can be 128 +different frames, each with 32 cursors. The coordinates associated +with a given cursor, and hence frame, are NDC for the pixel on which +the cursor is positioned. If a frame is not being displayed, a cursor +read for that frame will return NDC for the pixel that would appear at +the current cursor position if the frame were enabled. Note that the +NDC used in the cursor_set and cursor_read calls are relative to +the image planes in the display device; the fact the image data may +have come from a much larger user "world" is not, and can not be, +of any concern to the kernel code. + + Cursor 0 is special, and is not associated with a particular frame; +rather, the kernel is allowed to choose which frame to associate with +each cursor zero read or write. The IIS code picks the lowest numbered +frame that is on (being displayed). With split screen activated, a +frame can be "on" and not be seen; for cursor zero, what matters is +whether the frame video is active, not whether the split position +happens to be hiding the frame. The "key" value returned by the cursor +read routine is the frame number selected by the kernel. Cursor +IDS_CSPECIAL is also unusual, since it refers to the screen coordinates +and returns NDC for the screen. It is referred in the code as IDS_CRAW +(a "raw" cursor) and is needed for positioning the cursor at specific +points of the screen. + + The MATCH function requires that the frame and color information +of the control escape sequence point to the reference table; the +tables to be changed are given in the "data" part with the (IDS_EOD +terminated) frame sequence preceding the color information. The RW +field specifies which type of look-up table is to be changed. +.sp +.nh +Interface Routines + + The routines listed here are those used to implement the video +control package, and are found in the file "cvutil.x". +Arguments relating to image frames, image colors, display quadrants, +offset, range, and look-up table data are short integer arrays, +terminated by IDS_EOD. Cursor position (x and y) are NDC (hence, real). +All other arguments are integers. + +.ls cvclearg (frame, color) +Clears (erases) the given color (or colors) in the graphics frame given +by the argument "frame". For the IIS display, the "frame" argument +is not relevant, there being only one set of graphics frames. +.le +.ls cvcleari (frames) +Clears (erases) all bits in the given image display frames. +.le +.ls cv_rdbut +Reads the buttons on whatever device the kernel code associates with +this call, and returns an integer representing the button most recently +pressed. If none pressed, returns zero. +.le +.ls cv_wtbut +Same as cv_rdbut, but if no button pressed, waits until one is. This +routine will, therefore, always return a non-zero (positive) integer. +.le +.ls cv_rcur (cnum, x, y) +Reads the cursor "cnum" returning the NDC coordinates in x and y. The +mapping of cursor number to frame is described in the preceding +section: for cursors with numbers below IDS_CSET (128), the cursor +refers to the frame (cnum equal 5 means frame 5). +.le +.ls cv_scur (cnum, x, y) +Sets the cursor to the NDC given by x and y for the frame referenced by +cnum. +.le +.ls cv_scraw (x, y) +Sets the "raw cursor" to position (x,y). +.le +.ls cv_rcraw (x, y) +Reads the "raw cursor" position in (screen) NDC. +.le +.ls cvcur (cmd) +Turns the cursor on (cmd is IDS_ON) or off (IDS_OFF). +.le +.ls cvdisplay (instruction, device, frame, color, quad) +Turns on ("instruction" equals IDS_ON) image plane ("device" equals +IDS_DISPLAY_I) frame (or frames) in specified colors and quadrants. +Turn them off if "instruction" equals IDS_OFF. Manipulates graphics +planes instead if "device" equals IDS_DISPLAY_G. +.le +.ls cvmatch (type, refframe, refcolor, frames, color) +Copies the reference frame and reference color into the given frames +and color. For the IIS, "type" is either IDS_FRAME_LUT, referring to the +look-up tables associated with each frame, or IDS_OUTPUT_LUT, referring +to the global Output Function Memory tables. +.le +.ls cvoffset (color, data) +Sets the offset constants for the specified colors to values given in +"data"; if there are more colors given than corresponding data items, +the kernel will reuse the last data item as often as necessary. +.le +.ls cvpan (frames, x, y) +Moves the given frames so that the NDC position (x,y) is at the center +of the display. +.le +.ls cvrange (color, range) +Scales the output for the given colors; if there are more colors given +than corresponding range items, the kernel will reuse the last data item +as often as necessary. Range is a small number which specifies which +range the data is to be "put" in. For the IIS, there are only 4 useful +values (1,2,4, and 8); the kernel will map the requested value to the +next smallest legitimate one. +.le +.ls cvreset (code) +Resets the part of the display referenced by "code". For the IIS, a code +of IDS_R_HARD refers to (erasing) the image and graphics planes, IDS_R_MEDIUM +resets the various look-up tables, and IDS_R_SOFT resets the various registers +(such as zoom, scroll, range, split screen, and so forth). +.le +.ls cvsnap (filename, snap_color) +Creates an IRAF image file, named "filename", which represents the image +display video output for the specified color (IDS_SNAP_RED, IDS_SNAP_MONO, +etc). "filename" is a "char" array. The image is of the full display, +though, since the data is obtained from the kernel line by line via +get_cellarray calls, partial snapshots can be implemented easily. +.le +.ls cvsplit (x,y) +Sets the split screen point at NDC position (x,y). +.le +.ls cvtext (x, y, text, size) +Writes the given text at NDC position (x,y) in the specified size. +Currently, font and text direction are set to NORMAL. +.le +.ls cvwhich (frame) +Tells which frames are on. In the current implementation, this relies +on reading cursor 0: in this special case, the cursor variable passed +to ggcur() is changed by the kernel to reflect which frame it selected +(or ERR if no frame is active). +.le +.ls cvwlut (device, frames, color, data, n) +Writes the look-up tables associated with "frames" and "color". "device" +is IDS_FRAME_LUT or IDS_OUTPUT_LUT. The data to be written is given as +a series of line segments, and hence is described as a series of GKI +(x,y) pairs representing the line end points. For connected lines, +the first pair gives the first line segment starting coordinates, and all +following pairs the endpoints. The variable "n" gives the number of +values in "data"; there is no terminating IDS_EOD. +.le +.ls cvzoom (frames, power, x, y) +Zooms, to the given power, the specified frames with each frame +centered, after the zoom, at the given NDC position. +.le + + The following two support routines are included in the interface +package. +.ls cv_move (in, out) +Copies the short array "in" into the short array "out", up to and +including a trailing IDS_EOD. This procedure returns the number of +items copied. +.le +.ls cv_iset (frames) +Implements the image display escape sequence, with the bitplane +argument to that escape sequence set to "all". +.le +.ls cv_gset (colors) +Implements the graphics display escape sequence, with the image +argument to that escape sequence set to "all". +.le +.sp +.nh +Example + + The following code is used to pan (scroll) the image in response +to a changing cursor position. It is assumed that the "frame" array +consists of a list of frames to be panned together, terminated, as +is almost everything in this code, by IDS_EOD. +.nf + +# Pan subroutine + +procedure pansub (frames) + +short frames[ARB] # frames to pan + +int button +int cnum, cv_rdbut() +real x,y, xc, yc +real oldx, oldy + +begin + button = cv_rdbut() # clear buttons by reading them + call eprintf ("Press any button when done\n") + + # Where is cursor now? + # cv_rcraw uses the "RAW CURSOR" which reads and writes in + # screen (NDC) coordinates instead of image NDC. + + call cv_rcraw (xc,yc) + + # Pixel to NDC transformation is discussed in the file + # "Note.pixel" + + x = x_screen_center_in_NDC + y = y_screen_center_in_NDC + + call cv_scraw (x, y) # put cursor at screen center + + # Select a cursor---at least one per frame (conceptually at least) + + cnum = frames[1] + + # If cnum == IDS_EOD, the calling code did not select a frame. So, + # if cnum is 0, the kernel will select an active frame as the + # one to use when mapping NDC cursor positions to screen + # coordinates. + + if (cnum == IDS_EOD) + cnum = 0 + + # Determine NDC at screen center (where cursor was moved to) + # for frame of interest + call cv_rcur (cnum, x, y) + + # Restore cursor to original position + call cv_scraw (xc, yc) + + repeat { + oldx = xc + oldy = yc + repeat { + call cv_rcraw (xc, yc) + button = cv_rdbut() + } until ( (xc != oldx) || (yc != oldy) || (button > 0)) + # Determine change and reflect it about current screen + # center so image moves in direction cursor moves. + x = x - (xc - oldx) + y = y - (yc - oldy) + # If x or y are <0 or > 1.0, add or subtract 1.0 + "adjust x,y" + call cvpan (frames, x, y) + } until (button > 0) +end +.fi + [The call to cvpan may in fact need to be a series of calls, with +the array "frames" specifying one frame at a time, and (x,y) being the +new cursor position for that particular frame, so that differently panned +frames retain their relative offsets.] + The cursor and button routines are given here. +.nf + +# CV_RDBUT -- read button on trackball (or whatever) +# if none pressed, will get zero back + +int procedure cv_rdbut() + +int oldcnum +real x, y +int button +int gstati + +include "cv.com" + +begin + oldcnum = gstati (cv_gp, G_CURSOR) + call gseti (cv_gp, G_CURSOR, IDS_BUT_RD) + call ggcur (cv_gp, x, y, button) + call gseti (cv_gp, G_CURSOR, oldcnum) + return(button) +end + +# CV_RCUR -- read cursor. The cursor read/set routines do not restore +# the cursor number...this to avoid numerous stati/seti calls that +# usually are not needed. + +procedure cv_rcur (cnum, x, y) + +int cnum +real x,y +int junk + +include "cv.com" + +begin + call gseti (cv_gp, G_CURSOR, cnum) + call ggcur (cv_gp, x, y, junk) +end + +# CV_SCUR -- set cursor + +procedure cv_scur (cnum, x, y) + +int cnum +real x,y + +include "cv.com" + +begin + call gseti (cv_gp, G_CURSOR, cnum) + call gscur (cv_gp, x, y) +end + +# CV_SCRAW -- set raw cursor + +procedure cv_scraw (x, y) + +real x,y + +begin + call cv_scur (IDS_CRAW, x, y) +end +.fi + + The routine cv_move copies its first argument to the second up through +the required IDS_EOD termination, returning the number of items copied. +"cv_stack" is a pointer to a pre-allocated stack area that is used to +build the data array passed to the GIO escape function. + +.nf +# cvpan -- move the image(s) around + +procedure cvpan (frames, x, y) + +short frames[ARB] +real x,y # position in NDC +int count, cv_move() + +include "cv.com" + +begin + Mems[cv_stack] = IDS_SCROLL # Control Unit + Mems[cv_stack+1] = IDS_WRITE # Read/Write + + # Three is the number of data items (two coordinates) plus the + # terminating IDS_EOD. In many escape sequences, this number + # must be determined from the data rather than known in advance. + + Mems[cv_stack+2] = 3 + + # Move the frame data, which is of "unknown" length + + count = cv_move (frames, Mems[cv_stack+3]) + + # Color is unimportant here, but the color data must exist. The + # simplest solution is to use IDS_EOD by itself. + + Mems[cv_stack+3+count] = IDS_EOD # default to all colors + Mems[cv_stack+4+count] = 1 # (unused) offset + Mems[cv_stack+5+count] = x * GKI_MAXNDC + Mems[cv_stack+6+count] = y * GKI_MAXNDC + Mems[cv_stack+7+count] = IDS_EOD # for all frames + call gescape (cv_gp, IDS_CONTROL, Mems[cv_stack], count+8) +end +.fi +.endhelp diff --git a/pkg/images/tv/iis/ids/doc/Note.misc b/pkg/images/tv/iis/ids/doc/Note.misc new file mode 100644 index 00000000..4b3a22de --- /dev/null +++ b/pkg/images/tv/iis/ids/doc/Note.misc @@ -0,0 +1,8 @@ +To implement a full device save/restore, we need: +zdev_restore(fd) +zdev_save(fd) +zim_save(fd,ipl) +zgr_save(fd,gpl) +zim_restore(fd,ipl) +zgr_restore(fd,gpl) +...zgr are just entry points into zim_{save,restore}(fd,pl) diff --git a/pkg/images/tv/iis/ids/doc/Note.pixel b/pkg/images/tv/iis/ids/doc/Note.pixel new file mode 100644 index 00000000..91c0338f --- /dev/null +++ b/pkg/images/tv/iis/ids/doc/Note.pixel @@ -0,0 +1,106 @@ + Herein is described how pixel coordinates should be encoded into +GKI metacode units and how this data is then converted back to pixel numbers +by the "lower level" code. For concreteness, the discussion is based on +a 512 x 512 display, where the pixels are numbered from 1 to 512 (one-based) +or 0 to 511 ( zero based). Only the X axis is discussed, the Y axis +being treated identically. + GKI metacode ranges from 0 through 32767, for a total of 32768 +values. In NDC coordinates, the range is from 0.0 through 1.0. +These coordinates are show in the diagram following. +.sp +.nf +last GKI coordinate of pixel + 63 127 191 255 319 32703 32767(!) +pixel | | | | | | | +extent-- |<-->||<-->||<-->||<-->||<-->|| ... |<-->||<--->| + | | | | | | | +the |-----|-----|-----|-----|-----| ... |-----|-----| +pixels | | | | | | ... | | | + |-----|-----|-----|-----|-----| ... |-----|-----| +num- (1-b) 1 2 3 4 5 511 512 +bers (0-b) 0 1 2 3 4 510 511 + | | | | | | ... | | | +GKI 0 64 128 192 256 320 32640 32704 32767(!) + | | | | | | ... | | | +NDC 0.0 1/512 2/512 3/512 4/512 5/512 511/512 1.0 +.fi +.sp + The pixels are not points, but rather, in GKI/NDC space, have +"physical" extent. In NDC coordinates, the pixel boundaries are +easily calculated as (left boundary = zero-based pixel number / 512) +and (right boundary = 1-based pixel number / 512). In GKI coordinates, +each pixel spans 64 GKI units, with the left boundary given by +"zero-based pixel number times 64". The right boundary is then the +left boundary plus 64 and then actually references the next pixel. +That is, the left boundary is included in the pixel, while the right +boundary is not. +(Pixel 0 goes from 0 through 63, pixel one from 64 through 127, etc.) +This works for all pixels except the last one, which would have a +right boundary of 32768; in this special case, the right boundary +is defined to be 32767. As will be seen later on, this should cause +no difficulties. + Explicit reference to a particular pixel should, in GKI +coordinates, refer to the pixel's left (or for Y, lower) edge. Thus, +pixel 7 (one-based system) is, in GKI, 6*64 or 384. + Cell arrays are denoted by their lower-left and upper-right +corners, with the understanding that all pixels WITHIN this rectangle +are to be read/written. Thus, an array that covers (one-based) +(4,10) to (18, 29) implies that, in X, pixels 4 through 17 are referenced. +Therefore, the GKI coordinate range is from 3*64 up to 17*64, where +3*64 is the GKI coordinate for the left edge of pixel 4 and 17*64 is +the GKI coordinate for the right edge of pixel 17. (Remember, the +right edge of pixel 512 is 32767, not 32768.) + The (real) NDC coordinate that is then passed to the interface code +is determined by dividing the GKI coordinate by 32767. The interface +code will, ultimately, multiply by 32767 to give the GKI coordinates +passed to the lower level. + The lower level code translates the GKI coordinate values into +zero-based pixel numbers by multiplying by 512/32768 ( not 32767). +The (real) pixel numbers so determined are then truncated, and become +the ones to scroll to, zoom to, or put the cursor on. Therefore, +when refering to single pixels for such operations, use the left +boundary of the pixel as the desired GKI/NDC coordinate. + Pixel computation for cell arrays is somewhat more complicated. +The right boundary of a cell array can be the left boundary for +an adjacent cell array; if the simple truncation scheme were used, that +coordinate would be included in both cell array operations, which is not +acceptable (especially for hard copy devices where the resultant overplotting +would be, at best, objectionable). This problem gives rise to the following +algorithm. Left (and lower) positions are rounded up to the next pixel +boundary if the fractional position is greater than or equal 0.5. Right +(and upper) positions are rounded down to the next pixel boundary if the +fractional position is less than 0.5; since a fractional pixel value of 0.0 +is less than 0.5, the right/upper pixel will be decreased even if it is +already on a boundary. The truncated values are then used as the +INCLUSIVE range of pixels to read or write. (If the positions lie +within the same pixel, that pixel becomes the X (or Y) range. If the +positions are in adjacent pixels, the right pixel operation is +not done if the left pixel moves into the same pixel as the right one.) + With this algorithm, the right edge of the display (NDC=1.0, +GKI=32767) becomes position 511.98, which is not rounded down as the +fractional part is >= 0.5, and, which, when truncated, turns into 511 +which is what is desired as the (last) included pixel in the range. + + For zoomed (image) displays, fractional pixel coordinates are +possible in the sense that, for a zoom of 4, pixels 16.0, 16.25, +16.50, and 16.75, all refer to the same datum. When setting the cursor, +the lower level code must distinguish all these cases, which have GKI +values (from a one-based coordinate system) 960, 976, 992, and 1008. +The lower level code will return these fractional pixel values when reading +the cursor, but the integral value is the real reference to the data +point. However, calls to the getcell and putcell routines should use +16 (aka 960) or the cell array rounding will interfere with what is +wanted. This does restrict getcell calls from starting/ending in the middle +of a zoomed (replicated) pixel, but makes the behavior of getcell +the same as putcell, which cannot write into the middle of a zoomed pixel. + + In summary, users should reference individual pixels by +specifying their left (or lower) boundaries in GKI/NDC. For cursor +reference on zoomed displays, fractional (in the sense outlined above) +pixels may be referenced. Right (or upper) boundaries are used only +for cell arrays, and except for the very right-most, are determined by +the user in an operation similar to that for the left boundaries. GKI +coordinates that are a little too large (not more than 31 units for a +512 resolution device) will be rounded/truncated to the desired +coordinate. For cell array operations only, ones a little too small +will still address the correct pixel. diff --git a/pkg/images/tv/iis/ids/doc/file.doc b/pkg/images/tv/iis/ids/doc/file.doc new file mode 100644 index 00000000..504a8330 --- /dev/null +++ b/pkg/images/tv/iis/ids/doc/file.doc @@ -0,0 +1,90 @@ +Some notes on the fio system. + Binary files. + open the binary file with + fio_fd = fopnbf(dev_name, mode, zopn_dev, zard_dev, zawr_dev, + zawt_dev, zstt_dev, zcl_dev) + where dev_name is a char string, terminated with EOS, + mode is READ_ONLY, READ_WRITE, WRITE_ONLY, NEW_FILE, APPEND, + TEMP_FILE, NEW_COPY + and the z routines are for open, read, write, wait, get status, + and close ( see system interface reference manual). + + The fio_fd that is returned is then used in calls to read, write, and flush. + They have the form write(fio_fd, buffer, #_of_chars) + read (fio_fd, buffer, #_of_chars) + flush(fio_fd) + seek (fio_fd, loffset) + long = note (fio_fd) + The output data will be buffered in a buffer of CHAR size as set by + a kernel call to zstt(). This can be overridden by + fsetl(fio_fd, F_BUFSIZE, buffer_size_in_char) + Partially filled buffers can be forced out by "flush". + Input data is buffered up before being made available to the + user; if an i/o call is needed to fill the buffer and it returns with + an inadequate number of data items, then the read returns with fewer + than requested itmes. + The file system can be made to use an external (local) buffer by + fseti(fio_fd, F_BUFPTR, new_buffer) + For general image i/o, it is desirable to set the ASYNC parameter to YES + fseti(fio_fd, F_ASYNC, YES) + If the device has a specific block size, this can be set by + fseti(fio_fd, F_BLKSIZE, value); + the file system will use this value for checking validity of block offsets + in reads and writes. If the value is zero, the device is considered a + "streaming" device, and no checks are done. + +(from Doug) +The device block size parameter is set at open time by all call to ZSTT__. +FIO is permissive and allows one to set almost anything with FSET, but some +of the parameters are best considered read only. This is documented at the +parameter level in <fset.h>. + +Image displays are NOT streaming devices, they are random access, block +structured devices. If you wish to defeat block alignment checking then +ZSTT__ may return a block size of 1 char. Note that not all image displays +are addressable at the pixel level. Even those that are are may be most +efficiently accessed using line at a time i/o (block size equals 1 line). + +If the block size is set to 1 FIO will still access the device in chunks +the size of the FIO buffer. The file area is partitioned up into a series +of "pages" the size of the FIO buffer and FIO will fault these pages in and +out when doing i/o. The only advantages of a block size of 1 are that the +FIO buffers may be any size (not much of an advantage), and more significantly, +AREAD and AWRITE calls may be used to randomly access the device. The latter +are asynchronous and are not buffered, and are the lowest level of i/o +provided by FIO. + + The form for the z routines is + zopn_dev(dev_name, mode, channel) + zard_dev(channel, buffer, length, offset) + zawr_dev(channel, buffer, length, offset) + zawt_dev(channel, bytes_read/written) + zstt_dev(channel, what, lvalue) + zcl_dev (channel, status) + + where channel is some number to be used however the z routines want, but + in the simplest case and under UNIX, would be the file descriptor of the + open file as determined by zopn_dev, or, in case of error, is ERR. + length and offset are in BYTES. zstt_dev() will be handled locally. + +Bytes, yes, but the file offsets are one-indexed. See the System Interface +reference manual. + + Each of the z*_dev routines above, with the exception of zstt_dev, will + ultimately result in a call to one of the system z routines for binary + files: zopnbf, zardbf, zawrbf, zawtbf, zclsbf. These routines take + the same arguments as the z*_dev routines, with the exception that + unix_fd is to be substituted for channel. "unix_fd" is the actual + file descriptor that results from the "real" open of the device by + zopnbf. It does not need to be visible above the z*_dev routines. + +The FIO z-routines for a device do not necessarily resolve into calls to the +ZFIOBF driver. It is desirable to structure things this way if we can since +it reduces the size of the kernel, but if necessary the z-routines can be +system dependent. Since the IIS is data driven and is interfaced in UNIX +as a file we were able to use the existing ZFIOBF driver, resulting in a +very clean interface. New devices should also be interfaced this way if +possible. For various reasons a data stream interface is almost always +preferable to a control interface (like Sebok's Peritek driver). I would +seriously consider adding a layer on a control driven device driver to make +it appear to be data driven, if the driver itself could not be modified. diff --git a/pkg/images/tv/iis/ids/doc/iis.doc b/pkg/images/tv/iis/ids/doc/iis.doc new file mode 100644 index 00000000..450de91a --- /dev/null +++ b/pkg/images/tv/iis/ids/doc/iis.doc @@ -0,0 +1,172 @@ +.TL +The IIS Image Display +.AU +Richard Wolff +.br +Central Computer Services +National Optical Astronomy Observatories +Tucson, Arizona +.DA +.PP +The International Imaging Systems (IIS) Model 70f is a reasonably +flexible image display with some more advanced capabilities than the IPPS, +(and, sad to say, some less advanced ones as well). This note describes +the hardware so that the user can use the device to best advantage. +The Model 75, which is in use at CTIO, is more elaborate still, but its +fundamental properties are the same as the 70f boxes in use at NOAO. +.PP +The image display has four image planes (frames, memories), each of which +can hold a 512 x 512 8 bit image. (The hardware can support 12 such planes, +but only four are installed in the NOAO units.) These planes are loaded +directly from the host computer; while there is hardware to support a +13-bit input/8-bit output mapping during load, this is not currently used +at NOAO. The frames are numbered 1 through 4 and there is nothing to +distinguish one from another. More than one image plane may be displayed +at one time; this may create a rather messy screen image, but, of course, +the hardware doesn't care. +.PP +The image is generated by hardware that +addresses each pixel in turn, and sends the data at that location to the +video display. Panning (scrolling/roaming) is accomplished simply by +starting the address generation somewhere other than at the normal starting +place. +Each plane has its own starting address, which just means that each +plane can be panned independently. In contrast, on the model 70, +all planes zoom together. Zooming is done by pixel replication: +The master address generator +"stutters", duplicating an address 2, 4, or 8 times before moving on to +the next pixel (and duplicating each line 2, 4, or 8 times--an additional +complication, but a necessary one, which is of interest only to hardware types). +The master address is then added to the per-image start address +and the resulting address streams are used to generate +the per-image data streams, which are added together to form the final image. +The net result of this is an image on the screen, with user control of the +placement of each image plane, and with one overall "magnification" factor. +.PP +If more than one image is active, the pixel values for a given screen +position are \fBadded\fR together. Thus, with four image planes, each of +which has pixels that can range in value from 0 through 255, the output +image can have pixel values that range from 0 through 3060. Unfortunately, +the output hardware can handle only values from 0 through 1023. But, +fortunately, hardware has been included to allow the use to offset and +scale the data back to the allowed output range. We will look at that +in more detail later. +.PP +The hardware that determines which frames are to be displayed consists +of "gates" that enable or disable the frame output to the image screen. +These "gates" are controlled by various data bits in the hardware. +Conceptually, given the description in the previous paragraphs, one can +imagine one bit (on or off) for each image frame, and it is these +bits that the \fBdi\fR command turns on and off. However, there are +complications, one of which is the split screen mode. Split screen +hardware allows the user to specify a point, anywhere on the screen, +where the screen will be divided into (generally, unequally sized) quadrants. +The display control bits specify not only which images will be active, +but in which of the four quadrants they will be active. +There are four control bits per image plane, and so, any image can +be displayed in any number of quadrants (including none, which means the +image is "off"). +.PP +If one imagines the split screen point in the middle of the screen, then +four quadrants are visible, number 1 being the upper right, number 4 the bottom +right, etc. As the split screen point is moved to the upper left, quadrant +four increases in size and the other three decrease. When the split point +reaches the top left corner (\fIIRAF\fR coordinate (1,512)), only quadrant +four is left. Due to a hardware decision, this is the normal, non-split, +screen configuration, the one you get when you type the \fBs o\fR command. +It would make more sense to set the non-split position so the screen was +filled with quadrant one, but the hardware won't allow it. So, be +warned, if you have a split screen display, +and then reset the split point to the "unsplit" point, +what you see will be only what you had displayed in quadrant 4. +.PP +The model 70f is a color display, not monochrome, and this adds more +complexity. What happens is that the data from each enabled image plane +is replicated and sent to three \fIcolor pipelines\fR, +one for the \fIred\fR gun of the monitor, one for the \fIgreen\fR, +and one for the \fIblue\fR. If the pipeline data streams are +the same, we get a black and white image. If they differ, the +final screen image is colored. Since there are really three data streams +leaving each image plane, it should not be surprising that there are +display control bits for each color, as well as each quadrant, of each +image. Thus (and finally) there are 12 control bits, three colors in each +of four quadrants, for each image plane. One can set up a display with +different images in different quadrants, and each colored differently! +Of course, the coloration is somewhat primative as the choices are limited +to red on or off, green on or off, both red and green on (yellow), blue on +or off, etc. More control comes with look-up tables. +.PP +The data from the combined image planes is added together in the pipelines. +There are offset and range registers for each pipeline which allow you to +bias and scale the data. Offset allows you to add or subtract a 13 bit +number (+-4095) and range scales the data by a factor of 1,2,4, or 8. +These are of interest mostly when more than one image is combined; in this +case, the resulting stream of data should be adjusted so that it +has its most interesting data in the range 0 through 1023. +.PP +Why 1023? The reason is that after offset and range have taken their +toll, the data is "passed through" a 10 bit in/10 bit out look-up table. +Look-up tables are digital functions in which each input datum is used +as an index into a table and the resultant value that is thus "looked-up" +replaces the datum in the data stream. The look-up tables here +are known as the \fIoutput\fR +tables (or, as IIS would have it, the "Output Function Memories"). +There is one for +each of the three pipelines, and each accepts an input value of 10 bits, +which limits the data stream to 0 through 1023, +If the image data in the three pipelines are the same, and the output +tables are too, then a black and white image results. If, however, the +pipelines are identical but the tables are different, a colored image +results. Since this image is not a true color image, +but simply results from manipulating the three identical color +pipelines in differing ways, the result is called a pseudo-color image. +.PP +The simplest look-up table is a linear function, whose input values run +from 0 through 1023 and whose output values do the same. The trouble +with such a linear output table is that the usual case is a single image +being displayed, in which case the pipeline data is never more than 255. +With the unit slope table, the maximum output would be 255, which is +one-quarter of full intensity. A better table in this case would be one of +slope 4, so 255 would map to 1023 (maximum output). This is what the +default is, and above 255 input, all values are mapped to 1023. If, +however, two images are being displayed, then data values may be larger +than 255 (at overlap points), and as these all map to 1023, only full white +results. The range/offset registers may be of use here, or a different +output table should be used. +.PP +The output of the "output" tables is combined with the graphics and cursor +data and sent to the display screen. The graphics planes are one bit +deep; there are seven of them, and together with the cursor, they form +an "image" 8 bits deep. In this sense, the graphics planes are just +like image data, and in particular, they pan and zoom just as the +image planes do. Of course, the cursor is different. The graphics +planes are sent through a look-up table of their own, which determines +what happens when one graphics plane crosses/overlaps others and/or the +cursor. The resultant data replaces the pipeline data. The graphics +data can be added to the pipeline data instead of replacing it, but this +feature is not available in \fIcv\fR at this time. The cursor is really +a writable 46x64 bit array; thus, its shape can be changed, a feature +that may be made available to users. Note that there is no quadrant/split +screen control for the graphics planes. +.PP +The final complication, at least as far as the current software is +concerned, is that each image plane has its own set of three look-up +tables, one for each color. Thus, there are 4x3 frame look-up tables +and three output tables. The image tables affect only the data from +the associated image plane. It is the output of these tables that +forms the input to the three color pipelines. Each table is an 8 bit in/9 +bit out table, with the output being treated as a signed number (255 to +-256). (Combining 12 9 bit numbers (a full model 70f) can produce a 13 bit +number, which is why the offset hardware accepts 13 bit numbers.) In +the \fIcv\fR software, only positive numbers are used as output from +the tables. Typically, the image tables are loaded with linear +functions of varying slope and intercept. +.PP +With the two sets of tables, image and output, it is possible to create +all sorts of interesting pseudo-color images. One possibility is to +place the appropriate three mappings in the output tables so as to create +the color (for instance, red can be used only for pixels with large +values, blue for low values, green for middling ones). Then the image +tables can be set to adjust the contrast/stretch of the each image +individually, producing, one assumes, useful and/or delightful +pseudo-color images. diff --git a/pkg/images/tv/iis/ids/font.com b/pkg/images/tv/iis/ids/font.com new file mode 100644 index 00000000..ec1b0ec9 --- /dev/null +++ b/pkg/images/tv/iis/ids/font.com @@ -0,0 +1,207 @@ +# CHRTAB -- Table of strokes for the printable ASCII characters. Each character +# is encoded as a series of strokes. Each stroke is expressed by a single +# integer containing the following bitfields: +# +# 2 1 +# 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 +# | | | | | | | +# | | | +---------+ +---------+ +# | | | | | +# | | | X Y +# | | | +# | | +-- pen up/down +# | +---- begin paint (not used at present) +# +------ end paint (not used at present) +# +#------------------------------------------------------------------------------ + +# Define the database. + +short chridx[96] # character index in chrtab +short chrtab[800] # stroke data to draw the characters + +# Index into CHRTAB of each printable character (starting with SP). + +data (chridx(i), i=01,05) / 1, 3, 12, 21, 30/ +data (chridx(i), i=06,10) / 45, 66, 79, 85, 92/ +data (chridx(i), i=11,15) / 99, 106, 111, 118, 121/ +data (chridx(i), i=16,20) / 128, 131, 141, 145, 154/ +data (chridx(i), i=21,25) / 168, 177, 187, 199, 203/ +data (chridx(i), i=26,30) / 221, 233, 246, 259, 263/ +data (chridx(i), i=31,35) / 268, 272, 287, 307, 314/ +data (chridx(i), i=36,40) / 327, 336, 344, 352, 359/ +data (chridx(i), i=41,45) / 371, 378, 385, 391, 398/ +data (chridx(i), i=46,50) / 402, 408, 413, 425, 433/ +data (chridx(i), i=51,55) / 445, 455, 468, 473, 480/ +data (chridx(i), i=56,60) / 484, 490, 495, 501, 506/ +data (chridx(i), i=61,65) / 511, 514, 519, 523, 526/ +data (chridx(i), i=66,70) / 529, 543, 554, 563, 574/ +data (chridx(i), i=71,75) / 585, 593, 607, 615, 625/ +data (chridx(i), i=76,80) / 638, 645, 650, 663, 671/ +data (chridx(i), i=81,85) / 681, 692, 703, 710, 723/ +data (chridx(i), i=86,90) / 731, 739, 743, 749, 754/ +data (chridx(i), i=91,95) / 759, 764, 776, 781, 793/ +data (chridx(i), i=96,96) / 801/ + +# Stroke data. + +data (chrtab(i), i=001,005) / 36, 1764, 675, 29328, 585/ +data (chrtab(i), i=006,010) / 21063, 21191, 21193, 21065, 29383/ +data (chrtab(i), i=011,015) / 1764, 355, 29023, 351, 29027/ +data (chrtab(i), i=016,020) / 931, 29599, 927, 29603, 1764/ +data (chrtab(i), i=021,025) / 603, 29066, 842, 29723, 1302/ +data (chrtab(i), i=026,030) / 28886, 143, 29839, 1764, 611/ +data (chrtab(i), i=031,035) / 29256, 78, 20810, 21322, 21581/ +data (chrtab(i), i=036,040) / 21586, 21334, 20822, 20569, 20573/ +data (chrtab(i), i=041,045) / 20833, 21345, 29789, 1764, 419/ +data (chrtab(i), i=046,050) / 20707, 20577, 20574, 20700, 20892/ +data (chrtab(i), i=051,055) / 21022, 21025, 20899, 1187, 28744/ +data (chrtab(i), i=056,060) / 717, 21194, 21320, 21512, 21642/ +data (chrtab(i), i=061,065) / 21645, 21519, 21327, 21197, 1764/ +data (chrtab(i), i=066,070) / 1160, 20700, 20704, 20835, 21027/ +data (chrtab(i), i=071,075) / 21152, 21149, 20561, 20556, 20744/ +data (chrtab(i), i=076,080) / 21192, 29841, 1764, 611, 21023/ +data (chrtab(i), i=081,085) / 21087, 21155, 21091, 1764, 739/ +data (chrtab(i), i=086,090) / 21087, 21018, 21009, 21068, 29384/ +data (chrtab(i), i=091,095) / 1764, 547, 21151, 21210, 21201/ +data (chrtab(i), i=096,100) / 21132, 29192, 1764, 93, 29774/ +data (chrtab(i), i=101,105) / 608, 29259, 78, 29789, 1764/ +data (chrtab(i), i=106,110) / 604, 29260, 84, 29780, 1764/ +data (chrtab(i), i=111,115) / 516, 21062, 21065, 21001, 21000/ +data (chrtab(i), i=116,120) / 21064, 1764, 84, 29780, 1764/ +data (chrtab(i), i=121,125) / 585, 21063, 21191, 21193, 21065/ +data (chrtab(i), i=126,130) / 21191, 1764, 72, 29859, 1764/ +data (chrtab(i), i=131,135) / 419, 20573, 20558, 20872, 21320/ +data (chrtab(i), i=136,140) / 21646, 21661, 21347, 20899, 1764/ +data (chrtab(i), i=141,145) / 221, 21155, 29320, 1764, 95/ +data (chrtab(i), i=146,150) / 20835, 21411, 21663, 21655, 20556/ +data (chrtab(i), i=151,155) / 20552, 29832, 1764, 95, 20899/ +data (chrtab(i), i=156,160) / 21347, 21663, 21658, 21334, 29270/ +data (chrtab(i), i=161,165) / 854, 5266, 21644, 21320, 20872/ +data (chrtab(i), i=166,170) / 28749, 1764, 904, 21411, 21283/ +data (chrtab(i), i=171,175) / 20561, 20559, 21391, 911, 13455/ +data (chrtab(i), i=176,180) / 1764, 136, 21320, 21645, 21652/ +data (chrtab(i), i=181,185) / 21337, 20889, 20565, 20579, 29859/ +data (chrtab(i), i=186,190) / 1764, 83, 20888, 21336, 21651/ +data (chrtab(i), i=191,195) / 21645, 21320, 20872, 20557, 20563/ +data (chrtab(i), i=196,200) / 20635, 29347, 1764, 99, 21667/ +data (chrtab(i), i=201,205) / 29064, 1764, 355, 20575, 20570/ +data (chrtab(i), i=206,210) / 20822, 20562, 20556, 20808, 21384/ +data (chrtab(i), i=211,215) / 21644, 21650, 21398, 20822, 918/ +data (chrtab(i), i=216,220) / 5274, 21663, 21411, 20835, 1764/ +data (chrtab(i), i=221,225) / 648, 21584, 21656, 21662, 21347/ +data (chrtab(i), i=226,230) / 20899, 20574, 20568, 20883, 21331/ +data (chrtab(i), i=231,235) / 21656, 1764, 602, 21210, 21207/ +data (chrtab(i), i=236,240) / 21079, 21082, 21207, 592, 21069/ +data (chrtab(i), i=241,245) / 21197, 21200, 21072, 21197, 1764/ +data (chrtab(i), i=246,250) / 602, 21146, 21143, 21079, 21082/ +data (chrtab(i), i=251,255) / 21143, 585, 21132, 21136, 21072/ +data (chrtab(i), i=256,260) / 21071, 21135, 1764, 988, 20628/ +data (chrtab(i), i=261,265) / 29644, 1764, 1112, 28824, 144/ +data (chrtab(i), i=266,270) / 29776, 1764, 156, 21460, 28812/ +data (chrtab(i), i=271,275) / 1764, 221, 20704, 20899, 21218/ +data (chrtab(i), i=276,280) / 21471, 21466, 21011, 21007, 521/ +data (chrtab(i), i=281,285) / 20999, 21127, 21129, 21001, 21127/ +data (chrtab(i), i=286,290) / 1764, 908, 20812, 20560, 20571/ +data (chrtab(i), i=291,295) / 20831, 21407, 21659, 21651, 21521/ +data (chrtab(i), i=296,300) / 21393, 21331, 21335, 21210, 21018/ +data (chrtab(i), i=301,305) / 20887, 20883, 21009, 21201, 21331/ +data (chrtab(i), i=306,310) / 1764, 72, 20963, 21219, 29768/ +data (chrtab(i), i=311,315) / 210, 5074, 1764, 99, 21411/ +data (chrtab(i), i=316,320) / 21663, 21658, 21398, 20566, 918/ +data (chrtab(i), i=321,325) / 5266, 21644, 21384, 20552, 20579/ +data (chrtab(i), i=326,330) / 1764, 1165, 21320, 20872, 20557/ +data (chrtab(i), i=331,335) / 20574, 20899, 21347, 29854, 1764/ +data (chrtab(i), i=336,340) / 99, 21347, 21662, 21645, 21320/ +data (chrtab(i), i=341,345) / 20552, 20579, 1764, 99, 20552/ +data (chrtab(i), i=346,350) / 29832, 86, 13078, 99, 29859/ +data (chrtab(i), i=351,355) / 1764, 99, 20552, 86, 13078/ +data (chrtab(i), i=356,360) / 99, 29859, 1764, 722, 21650/ +data (chrtab(i), i=361,365) / 29832, 1165, 4936, 20872, 20557/ +data (chrtab(i), i=366,370) / 20574, 20899, 21347, 29854, 1764/ +data (chrtab(i), i=371,375) / 99, 28744, 85, 5269, 1160/ +data (chrtab(i), i=376,380) / 29859, 1764, 291, 29603, 611/ +data (chrtab(i), i=381,385) / 4680, 328, 29576, 1764, 77/ +data (chrtab(i), i=386,390) / 20872, 21256, 21581, 29795, 1764/ +data (chrtab(i), i=391,395) / 99, 28744, 1160, 20887, 82/ +data (chrtab(i), i=396,400) / 13475, 1764, 99, 20552, 29832/ +data (chrtab(i), i=401,405) / 1764, 72, 20579, 21077, 21603/ +data (chrtab(i), i=406,410) / 29768, 1764, 72, 20579, 21640/ +data (chrtab(i), i=411,415) / 29859, 1764, 94, 20899, 21347/ +data (chrtab(i), i=416,420) / 21662, 21645, 21320, 20872, 20557/ +data (chrtab(i), i=421,425) / 20574, 862, 29859, 1764, 72/ +data (chrtab(i), i=426,430) / 20579, 21411, 21663, 21656, 21396/ +data (chrtab(i), i=431,435) / 20564, 1764, 94, 20557, 20872/ +data (chrtab(i), i=436,440) / 21320, 21645, 21662, 21347, 20899/ +data (chrtab(i), i=441,445) / 20574, 536, 29828, 1764, 72/ +data (chrtab(i), i=446,450) / 20579, 21411, 21663, 21657, 21398/ +data (chrtab(i), i=451,455) / 20566, 918, 13448, 1764, 76/ +data (chrtab(i), i=456,460) / 20808, 21384, 21644, 21649, 21397/ +data (chrtab(i), i=461,465) / 20822, 20570, 20575, 20835, 21411/ +data (chrtab(i), i=466,470) / 29855, 1764, 648, 21155, 99/ +data (chrtab(i), i=471,475) / 29923, 1764, 99, 20557, 20872/ +data (chrtab(i), i=476,480) / 21320, 21645, 29859, 1764, 99/ +data (chrtab(i), i=481,485) / 21064, 29795, 1764, 99, 20808/ +data (chrtab(i), i=486,490) / 21141, 21448, 29923, 1764, 99/ +data (chrtab(i), i=491,495) / 29832, 72, 29859, 1764, 99/ +data (chrtab(i), i=496,500) / 21079, 29256, 599, 13411, 1764/ +data (chrtab(i), i=501,505) / 99, 21667, 20552, 29832, 1764/ +data (chrtab(i), i=506,510) / 805, 20965, 20935, 29447, 1764/ +data (chrtab(i), i=511,515) / 99, 29832, 1764, 421, 21221/ +data (chrtab(i), i=516,520) / 21191, 29063, 1764, 288, 21091/ +data (chrtab(i), i=521,525) / 29600, 1764, 3, 29891, 1764/ +data (chrtab(i), i=526,530) / 547, 29341, 1764, 279, 21207/ +data (chrtab(i), i=531,535) / 21396, 21387, 21127, 20807, 20555/ +data (chrtab(i), i=536,540) / 20558, 20753, 21201, 21391, 907/ +data (chrtab(i), i=541,545) / 13447, 1764, 99, 28744, 76/ +data (chrtab(i), i=546,550) / 4424, 21256, 21516, 21523, 21271/ +data (chrtab(i), i=551,555) / 20823, 20563, 1764, 981, 21271/ +data (chrtab(i), i=556,560) / 20823, 20563, 20556, 20808, 21256/ +data (chrtab(i), i=561,565) / 29642, 1764, 1043, 4887, 20823/ +data (chrtab(i), i=566,570) / 20563, 20556, 20808, 21256, 21516/ +data (chrtab(i), i=571,575) / 1032, 29731, 1764, 80, 5136/ +data (chrtab(i), i=576,580) / 21523, 21271, 20823, 20563, 20556/ +data (chrtab(i), i=581,585) / 20808, 21256, 29707, 1764, 215/ +data (chrtab(i), i=586,590) / 29591, 456, 20958, 21153, 21409/ +data (chrtab(i), i=591,595) / 29727, 1764, 67, 20800, 21248/ +data (chrtab(i), i=596,600) / 21508, 29719, 1043, 21271, 20823/ +data (chrtab(i), i=601,605) / 20563, 20556, 20808, 21256, 21516/ +data (chrtab(i), i=606,610) / 1764, 99, 28744, 83, 4439/ +data (chrtab(i), i=611,615) / 21271, 21523, 29704, 1764, 541/ +data (chrtab(i), i=616,620) / 21019, 21147, 21149, 21021, 21147/ +data (chrtab(i), i=621,625) / 533, 21077, 29256, 1764, 541/ +data (chrtab(i), i=626,630) / 21019, 21147, 21149, 21021, 21147/ +data (chrtab(i), i=631,635) / 533, 21077, 21058, 20928, 20736/ +data (chrtab(i), i=636,640) / 28802, 1764, 99, 28744, 84/ +data (chrtab(i), i=641,645) / 29530, 342, 13320, 1764, 483/ +data (chrtab(i), i=646,650) / 21089, 21066, 29384, 1764, 87/ +data (chrtab(i), i=651,655) / 28744, 584, 21076, 84, 4375/ +data (chrtab(i), i=656,660) / 20951, 21076, 21207, 21399, 21588/ +data (chrtab(i), i=661,665) / 29768, 1764, 87, 28744, 83/ +data (chrtab(i), i=666,670) / 20823, 21271, 21523, 29704, 1764/ +data (chrtab(i), i=671,675) / 83, 20556, 20808, 21256, 21516/ +data (chrtab(i), i=676,680) / 21523, 21271, 20823, 20563, 1764/ +data (chrtab(i), i=681,685) / 87, 28736, 83, 20823, 21271/ +data (chrtab(i), i=686,690) / 21523, 21516, 21256, 20808, 20556/ +data (chrtab(i), i=691,695) / 1764, 1047, 29696, 1036, 21256/ +data (chrtab(i), i=696,700) / 20808, 20556, 20563, 20823, 21271/ +data (chrtab(i), i=701,705) / 21523, 1764, 87, 28744, 83/ +data (chrtab(i), i=706,710) / 20823, 21271, 29716, 1764, 74/ +data (chrtab(i), i=711,715) / 20808, 21256, 21514, 21518, 21264/ +data (chrtab(i), i=716,720) / 20816, 20562, 20565, 20823, 21271/ +data (chrtab(i), i=721,725) / 21461, 1764, 279, 29591, 970/ +data (chrtab(i), i=726,730) / 21320, 21128, 21002, 21025, 1764/ +data (chrtab(i), i=731,735) / 87, 20556, 20808, 21256, 21516/ +data (chrtab(i), i=736,740) / 1032, 29719, 1764, 151, 21064/ +data (chrtab(i), i=741,745) / 29719, 1764, 87, 20808, 21077/ +data (chrtab(i), i=746,750) / 21320, 29783, 1764, 151, 29704/ +data (chrtab(i), i=751,755) / 136, 29719, 1764, 87, 21064/ +data (chrtab(i), i=756,760) / 320, 29783, 1764, 151, 21527/ +data (chrtab(i), i=761,765) / 20616, 29704, 1764, 805, 21157/ +data (chrtab(i), i=766,770) / 21026, 21017, 20951, 20822, 20949/ +data (chrtab(i), i=771,775) / 21011, 21001, 21127, 21255, 1764/ +data (chrtab(i), i=776,780) / 611, 29273, 594, 29256, 1764/ +data (chrtab(i), i=781,785) / 485, 21093, 21218, 21209, 21271/ +data (chrtab(i), i=786,790) / 21398, 21269, 21203, 21193, 21063/ +data (chrtab(i), i=791,795) / 29127, 1764, 83, 20758, 20950/ +data (chrtab(i), i=796,800) / 21265, 21457, 29844, 1764, 0/ diff --git a/pkg/images/tv/iis/ids/font.h b/pkg/images/tv/iis/ids/font.h new file mode 100644 index 00000000..c33dc6ee --- /dev/null +++ b/pkg/images/tv/iis/ids/font.h @@ -0,0 +1,29 @@ +# NCAR font definitions. + +define CHARACTER_START 32 +define CHARACTER_END 126 +define CHARACTER_HEIGHT 26 +define CHARACTER_WIDTH 17 + +define FONT_LEFT 0 +define FONT_CENTER 9 +define FONT_RIGHT 27 +define FONT_TOP 36 +define FONT_CAP 34 +define FONT_HALF 23 +define FONT_BASE 9 +define FONT_BOTTOM 0 +define FONT_WIDTH 27 +define FONT_HEIGHT 36 + +define COORD_X_START 7 +define COORD_Y_START 1 +define COORD_PEN_START 13 +define COORD_X_LEN 6 +define COORD_Y_LEN 6 +define COORD_PEN_LEN 1 + +define PAINT_BEGIN_START 14 +define PAINT_END_START 15 +define PAINT_BEGIN_LEN 1 +define PAINT_END_LEN 1 diff --git a/pkg/images/tv/iis/ids/idscancel.x b/pkg/images/tv/iis/ids/idscancel.x new file mode 100644 index 00000000..b03aac61 --- /dev/null +++ b/pkg/images/tv/iis/ids/idscancel.x @@ -0,0 +1,19 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <fset.h> +include "../lib/ids.h" + +# IDS_CANCEL -- Cancel any buffered output. + +procedure ids_cancel (dummy) + +int dummy # not used at present +include "../lib/ids.com" + +begin + if (i_kt == NULL) + return + + # Just cancel any output in the FIO stream + call fseti (i_out, F_CANCEL, OK) +end diff --git a/pkg/images/tv/iis/ids/idschars.x b/pkg/images/tv/iis/ids/idschars.x new file mode 100644 index 00000000..4a53ad56 --- /dev/null +++ b/pkg/images/tv/iis/ids/idschars.x @@ -0,0 +1,20 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../lib/ids.h" + +# IDSCHARS -- Write characters in the current plane + +procedure idschars (xs, ys, data, length, size, orien) + +int xs, ys # starting coordinates, GKI +char data[ARB] # the characters +int length # how many +int size # how big +int orien # character orientation + + +include "../lib/ids.com" + +begin + # Not implemented yet. +end diff --git a/pkg/images/tv/iis/ids/idsclear.x b/pkg/images/tv/iis/ids/idsclear.x new file mode 100644 index 00000000..6b6488d4 --- /dev/null +++ b/pkg/images/tv/iis/ids/idsclear.x @@ -0,0 +1,16 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../lib/ids.h" + +# IDS_CLEAR -- Clear an image frame. + +procedure ids_clear (dummy) + +int dummy # not used at present +include "../lib/ids.com" + +begin + if (i_kt == NULL) + return + call zclear(Mems[IDS_FRAME(i_kt)], Mems[IDS_BITPL(i_kt)], i_image) +end diff --git a/pkg/images/tv/iis/ids/idsclose.x b/pkg/images/tv/iis/ids/idsclose.x new file mode 100644 index 00000000..d77ade09 --- /dev/null +++ b/pkg/images/tv/iis/ids/idsclose.x @@ -0,0 +1,19 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../lib/ids.h" + +# IDS_CLOSE -- Close the image display kernel. +# Free up storage. + +procedure ids_close() + +include "../lib/ids.com" + +begin + call close(i_out) + call mfree (IDS_FRAME(i_kt), TY_SHORT) + call mfree (IDS_BITPL(i_kt), TY_SHORT) + call mfree (IDS_SBUF(i_kt), TY_CHAR) + call mfree (i_kt, TY_STRUCT) + i_kt = NULL +end diff --git a/pkg/images/tv/iis/ids/idsclosews.x b/pkg/images/tv/iis/ids/idsclosews.x new file mode 100644 index 00000000..40f7e40e --- /dev/null +++ b/pkg/images/tv/iis/ids/idsclosews.x @@ -0,0 +1,15 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../lib/ids.h" + +# IDS_CLOSEWS -- Close the named workstation. + +procedure ids_closews (devname, n) + +short devname[n] # device name (not used) +int n # length of device name +include "../lib/ids.com" + +begin + call ids_flush(0) +end diff --git a/pkg/images/tv/iis/ids/idscround.x b/pkg/images/tv/iis/ids/idscround.x new file mode 100644 index 00000000..fc70a813 --- /dev/null +++ b/pkg/images/tv/iis/ids/idscround.x @@ -0,0 +1,61 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../lib/ids.h" +include <gki.h> + +# IDS_CROUND -- coordinate rounding. Since putcell and other similar +# calls are defined to include both the lower-left corner and the upper-right +# corners of the desired rectangle, it is necessary to "round" the +# coordinates so that adjacent rectangles do not have overlapping edges. +# This could have been done by agreeing that the top and right edges of the +# rectangle are not part of it, but this was not done in the GKI definition. +# Hence, here, we adopt the notion that if (for example) the upper y coordinate +# is in the top half of a pixel, that pixel is included and if the lower y +# coordinate is in the bottom half of a pixel, likewise, that pixel is included. +# Otherwise, the pixels are excluded from putcell. The x coordinates are +# treated similarly. +# The code depends on the fact that lower is <= upper, that upper will be +# at most GKI_MAXNDC, and that the device resolution will never be as much +# as (GKI_MAXNDC+1)/2. The last requirement stems from the fact that if +# the resolution were that high, each pixel would be 2 GKI units and +# the "rounding" based on whether or not we are in the upper or lower half +# of a pixel would probably fail due to rounding/truncation errors. + +procedure ids_cround(lower, upper, res) + +int lower, upper +real res # device resolution + +real low, up +real factor + +begin + factor = res/(GKI_MAXNDC+1) + low = real(lower) * factor + up = real(upper) * factor + + # if boundaries result in same row, return + if ( int(low) == int(up) ) + return + + # if low is in upper half of device pixel, round up + if ( (low - int(low)) >= 0.5 ) { + low = int(low) + 1 + # don't go to or beyond upper bound + if ( low < up ) { + # low already incremented; + # ... 0.2 just for "rounding protection" + lower = (low + 0.2)/factor + # if now reference same cell, return + if ( int(low) == int(up) ) + return + } + } + + # if "up" in bottom half of pixel, drop down one. Note that + # due to two "==" tests above, upper will not drop below lower. + # 0.2 means drop partway down into pixel below; calling code will + # truncate. + if ( (up - int(up)) < 0.5 ) + upper = (real(int(up)) - 0.2)/factor +end diff --git a/pkg/images/tv/iis/ids/idsdrawch.x b/pkg/images/tv/iis/ids/idsdrawch.x new file mode 100644 index 00000000..8372fac2 --- /dev/null +++ b/pkg/images/tv/iis/ids/idsdrawch.x @@ -0,0 +1,67 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <math.h> +include <gki.h> +include <gset.h> +include "font.h" + +define ITALIC_TILT 0.30 # fraction of xsize to tilt italics at top + + +# IDS_DRAWCHAR -- Draw a character of the given size and orientation at the +# given position. + +procedure ids_drawchar (ch, x, y, xsize, ysize, orien, font) + +char ch # character to be drawn +int x, y # lower left GKI coords of character +int xsize, ysize # width, height of char in GKI units +int orien # orientation of character (0 degrees normal) +int font # desired character font + +real px, py, sx, sy, coso, sino, theta +int stroke, tab1, tab2, i, pen +int bitupk() +include "font.com" + +begin + if (ch < CHARACTER_START || ch > CHARACTER_END) + i = '?' - CHARACTER_START + 1 + else + i = ch - CHARACTER_START + 1 + + # Set the font. + call ids_font (font) + + tab1 = chridx[i] + tab2 = chridx[i+1] - 1 + + theta = -DEGTORAD(orien) + coso = cos(theta) + sino = sin(theta) + + do i = tab1, tab2 { + stroke = chrtab[i] + px = bitupk (stroke, COORD_X_START, COORD_X_LEN) + py = bitupk (stroke, COORD_Y_START, COORD_Y_LEN) + pen = bitupk (stroke, COORD_PEN_START, COORD_PEN_LEN) + + # Scale size of character. + px = px / FONT_WIDTH * xsize + py = py / FONT_HEIGHT * ysize + + # The italic font is implemented applying a tilt. + if (font == GT_ITALIC) + px = px + ((py / ysize) * xsize * ITALIC_TILT) + + # Rotate and shift. + sx = x + px * coso + py * sino + sy = y - px * sino + py * coso + + # Draw the line segment or move pen. + if (pen == 0) + call ids_point (short(sx), short(sy), false) + else + call ids_vector (short(sx), short(sy)) + } +end diff --git a/pkg/images/tv/iis/ids/idsescape.x b/pkg/images/tv/iis/ids/idsescape.x new file mode 100644 index 00000000..3c0c404f --- /dev/null +++ b/pkg/images/tv/iis/ids/idsescape.x @@ -0,0 +1,115 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <gki.h> +include "../lib/ids.h" + +# IDS_ESCAPE -- Pass a device dependent instruction on to the kernel. +# Most of the display control work is done here. + +procedure ids_escape (fn, instruction, nwords) + +int fn # function code +short instruction[ARB] # instruction data words +int nwords # length of instruction + +pointer p,q +int ids_dcopy() +short frames[IDS_MAXIMPL+2] # storage for frame data +short color[IDS_MAXGCOLOR+1] # ditto for color +short bitpl[IDS_MAXBITPL+1] # ditto for graphics bit plane +short quad[5] # 4 quadrant information +int count, count2, total +int junk + +short gki[GKI_ESCAPE_LEN] +data gki[1] /BOI/, gki[2] /GKI_ESCAPE/ + +include "../lib/ids.com" + +begin + switch(fn) { + + case IDS_RESET: + call ids_reset(instruction[1]) + + case IDS_SET_IP: + p = IDS_FRAME(i_kt) + count = ids_dcopy(instruction[1], Mems[p]) + call ids_expand(Mems[p],i_maxframes, true) + q = IDS_BITPL(i_kt) + junk = ids_dcopy ( instruction[count+1], Mems[q]) + call ids_expand(Mems[q],IDS_MAXBITPL, false) + i_image = true + call zsetup (Mems[p], Mems[q], i_image) + + case IDS_SET_GP: + p = IDS_FRAME(i_kt) + count = ids_dcopy(instruction[1], Mems[p]) + call ids_expand(Mems[p],i_maxgraph, false) + q = IDS_BITPL(i_kt) + junk = ids_dcopy ( instruction[count+1], Mems[q]) + call ids_expand(Mems[q],IDS_MAXBITPL, false) + i_image = false + call zsetup (Mems[p], Mems[q], i_image) + + case IDS_DISPLAY_I: + count = ids_dcopy(instruction[2], frames[1]) + call ids_expand(frames[1], i_maxframes, true) + count2 = ids_dcopy (instruction[2+count], color[1]) + call ids_expand(color[1], IDS_MAXGCOLOR, false) + total = count + count2 + count = ids_dcopy(instruction[total+2], quad[1]) + call ids_expand(quad[1], 4, false) + call zdisplay_i(instruction[1], frames[1], color, quad) + + case IDS_DISPLAY_G: + count = ids_dcopy(instruction[2], bitpl[1]) + call ids_expand(bitpl[1], i_maxgraph, false) + count2 = ids_dcopy (instruction[2+count], color[1]) + call ids_expand(color[1], IDS_MAXGCOLOR, false) + total = count + count2 + count = ids_dcopy(instruction[total+2], quad[1]) + call ids_expand(quad[1], 4, false) + call zdisplay_g(instruction[1], bitpl, color, quad) + + case IDS_SAVE: + call idssave(instruction[1], nwords) + + case IDS_RESTORE: + call idsrestore(instruction[1], nwords) + + case IDS_CONTROL: + count = ids_dcopy(instruction[IDS_CTRL_FRAME], frames[1]) + call ids_expand(frames[1], i_maxframes, true) + count2 = ids_dcopy (instruction[IDS_CTRL_FRAME+count], color[1]) + call ids_expand(color[1], IDS_MAXGCOLOR, false) + total = count + count2 + call zcontrol(instruction[IDS_CTRL_REG], + instruction[IDS_CTRL_RW], + frames[1], color[1], + instruction[total+IDS_CTRL_FRAME], + instruction[IDS_CTRL_N], + instruction[total+IDS_CTRL_FRAME+1] ) + # if a read, would like to return the information in gki format + # but no mechanism (yet?) for that + } +end + +# IDS_DCOPY -- copy frame and bitplane information; return the number of +# items copied, including the IDS_EOD (whose presence is required and assumed). + +int procedure ids_dcopy(from, to) + +short from[ARB] # from this storage +short to[ARB] # to this area + +int i # count + +begin + i = 0 + repeat { + i = i + 1 + to[i] = from[i] + } until ( to[i] == IDS_EOD ) + return (i) +end diff --git a/pkg/images/tv/iis/ids/idsfa.x b/pkg/images/tv/iis/ids/idsfa.x new file mode 100644 index 00000000..b2d162c8 --- /dev/null +++ b/pkg/images/tv/iis/ids/idsfa.x @@ -0,0 +1,16 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../lib/ids.h" + +# IDS_FILLAREA -- Fill a closed area. + +procedure ids_fillarea (p, npts) + +short p[ARB] # points defining line +int npts # number of points, i.e., (x,y) pairs +include "../lib/ids.com" + +begin + # Not implemented yet. + call ids_polyline (p, npts) +end diff --git a/pkg/images/tv/iis/ids/idsfaset.x b/pkg/images/tv/iis/ids/idsfaset.x new file mode 100644 index 00000000..a8807766 --- /dev/null +++ b/pkg/images/tv/iis/ids/idsfaset.x @@ -0,0 +1,18 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <gki.h> +include "../lib/ids.h" + +# IDS_FASET -- Set the fillarea attributes. + +procedure ids_faset (gki) + +short gki[ARB] # attribute structure +pointer fa +include "../lib/ids.com" + +begin + fa = IDS_FAAP(i_kt) + FA_STYLE(fa) = gki[GKI_FASET_FS] + FA_COLOR(fa) = gki[GKI_FASET_CI] +end diff --git a/pkg/images/tv/iis/ids/idsflush.x b/pkg/images/tv/iis/ids/idsflush.x new file mode 100644 index 00000000..cd177d40 --- /dev/null +++ b/pkg/images/tv/iis/ids/idsflush.x @@ -0,0 +1,18 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../lib/ids.h" + +# IDS_FLUSH -- Flush output. + +procedure ids_flush (dummy) + +int dummy # not used at present +include "../lib/ids.com" + +begin + if (i_kt == NULL) + return + + # We flush the FIO stream. + call flush (i_out) +end diff --git a/pkg/images/tv/iis/ids/idsfont.x b/pkg/images/tv/iis/ids/idsfont.x new file mode 100644 index 00000000..b3109f83 --- /dev/null +++ b/pkg/images/tv/iis/ids/idsfont.x @@ -0,0 +1,40 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <gki.h> +include <gset.h> +include "../lib/ids.h" + +# IDS_FONT -- Set the character font. The roman font is normal. Bold is +# implemented by increasing the vector line width; care must be taken to +# set IDS_WIDTH so that the other vector drawing procedures remember to +# change the width back. The italic font is implemented in the character +# generator by a geometric transformation. + +procedure ids_font (font) + +int font # code for font to be set +int pk1, pk2, width +include "../lib/ids.com" + +begin + pk1 = GKI_PACKREAL(1.0) + pk2 = GKI_PACKREAL(2.0) + + width = IDS_WIDTH(i_kt) + + if (font == GT_BOLD) { + if (width != pk2) { + # Name collision with ids_open !! + # call ids_optn (*"inten", *"high") + width = pk2 + } + } else { + if (GKI_UNPACKREAL(width) > 1.5) { + # Name collision with ids_open !! + # call ids_optn (*"inten", *"low") + width = pk1 + } + } + + IDS_WIDTH(i_kt) = width +end diff --git a/pkg/images/tv/iis/ids/idsgcell.x b/pkg/images/tv/iis/ids/idsgcell.x new file mode 100644 index 00000000..6ba8245f --- /dev/null +++ b/pkg/images/tv/iis/ids/idsgcell.x @@ -0,0 +1,170 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <gki.h> +include <gset.h> +include "../lib/ids.h" + +# IDS_GETCELLARRAY -- Fetch a cell array, i.e., two dimensional array of pixels +# (greylevels or colors). + +procedure ids_getcellarray (nc, nr, ax1,ay1, ax2,ay2) + +int nc, nr # number of pixels in X and Y +int ax1, ay1 # lower left corner of input window +int ax2, ay2 # upper right corner of input window + +int x1, y1, x2, y2 +int nx,ny # number of device pixels in x and y +real px1, px2, py1, py2 + +real skip_x, skip_y, sx, sy +real blockx, blocky, bcy +int i, j, startrow, element +real xres, yres +pointer sp, cell +pointer mp # final data pointer to "array" m +bool ca, use_orig, new_row + +include "../lib/ids.com" + +begin + + # determine if can do real cell array. + + ca = (IDS_CELLARRAY(i_kt) != 0) + if ( !ca ) + return + + skip_x = 1.0 + skip_y = 1.0 + blockx = 1.0 + blocky = 1.0 + + xres = real(i_xres) + yres = real(i_yres) + + # adjust pixels for edges + x1 = ax1 + x2 = ax2 + y1 = ay1 + y2 = ay2 + call ids_cround(x1,x2,xres) + call ids_cround(y1,y2,yres) + + # find out how many real pixels we have to fetch + + px1 = real(x1) * xres /(GKI_MAXNDC+1) + py1 = real(y1) * yres /(GKI_MAXNDC+1) + px2 = real(x2) * xres /(GKI_MAXNDC+1) + py2 = real(y2) * yres /(GKI_MAXNDC+1) + + nx = int( px2 ) - int( px1 ) + 1 + ny = int( py2 ) - int( py1 ) + 1 + + # if too many data points in input, set skip. If skip is close + # enough to one, set it to one. + # set block replication factors - will be > 1.0 if too few input points. + # cannot set to 1.0 if "close" enough, since, if > 1.0, we don't have + # enough points and so *some* have to be replicated. + + if ( nx > nc ) { + skip_x = real(nx)/nc + if ( (skip_x - 1.0)*(nc-1) < 1.0 ) + skip_x = 1.0 + } else + blockx = real(nc)/nx + + if ( ny > nr ) { + skip_y = real(ny)/nr + if ( (skip_y - 1.0)*(nr-1) < 1.0 ) + skip_y = 1.0 + } else + blocky = real(nr)/ny + + # initialize counters + + call smark(sp) + + # allocate storage for output + + call salloc (mp, nc*nr, TY_SHORT) + sy = 0 + bcy = blocky + startrow = 1 + + # see if we can use original data ... no massaging + # also set the initial value of the new_row flag, which tells + # if we have to rebuild the row data + # note that if blockx > 1.0, skip_x must be 1.0, and vv + + if ( (skip_x == 1.0) && (blockx == 1.0) ) { + use_orig = true + } else { + use_orig = false + # allocate storage for a row of pixels. + call salloc ( cell, nx, TY_SHORT) + } + new_row = true + + # do it + + for ( i = 1; i <= nr ; i = i + 1) { + + # fetch the row data. The reading routine will figure out + # how to read from the various individual frames and bitplanes. + + if ( new_row) { + if (!i_snap) + call zseek (i_out, int(px1), int(py1)+int(sy+0.5)) + if ( use_orig ) + # just copy it in + if (i_snap) + call do_snap (Mems[mp+startrow-1], nx, int(px1), + int(py1)+int(sy+0.5)) + else + call read (i_out, Mems[mp+startrow-1], nx) + else + # into Mems for rework + if (i_snap) + call do_snap (Mems[cell], nx, int(px1), + int(py1)+int(sy+0.5)) + else + call read (i_out, Mems[cell], nx) + } + + # rework the row data + + if ( !use_orig && new_row ) { + if ( skip_x == 1.0) + call ids_blockit(Mems[cell], Mems[mp+startrow-1], nc, + blockx) + else { + sx = 0 + for ( j = 1; j <= nc; j = j + 1) { + element = int(sx+0.5) + Mems[mp+startrow-1+j-1] = Mems[cell + element] + sx = sx + skip_x + } + } + } + # if don't need new row of input data, duplicate the + # previous one by copying within the "m" array + if ( ! new_row ) + call amovs (Mems[mp+startrow-1-nc], Mems[mp+startrow-1], nc) + + #advance a row + + startrow = startrow + nc + if ( bcy <= real(i) ) { + sy = sy + skip_y + bcy = bcy + blocky + new_row = true + } else { + new_row = false + } + } + + call gki_retcellarray (i_in, Mems[mp], nr * nc) + call sfree(sp) +end diff --git a/pkg/images/tv/iis/ids/idsgcur.x b/pkg/images/tv/iis/ids/idsgcur.x new file mode 100644 index 00000000..d3c0a1c6 --- /dev/null +++ b/pkg/images/tv/iis/ids/idsgcur.x @@ -0,0 +1,33 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../lib/ids.h" + +# IDS_GETCURSOR -- Get the position of a cursor. This is the low level +# cursor read procedure. Reading the image cursor is only possible when +# the ids kernel is run interactively, i.e., when the kernel is linked +# into the CL process, which owns the terminal. A raw binary read is required. +# The cursor value is returned as a GKI structure on the stream "i_in", +# i.e., it is sent back to the process which requested it. + +procedure ids_getcursor (cursor) + +int cursor + +int cur +int x, y, key + +include "../lib/ids.com" + +begin + cur = cursor + if ( cur > IDS_CSPECIAL ) { + switch( cur ) { + case IDS_BUT_RD, IDS_BUT_WT: + call iisbutton( cur, x, y, key) + } + } else + call zcursor_read (cur, x, y, key) + + call gki_retcursorvalue (i_in, x, y, key, cur) + call flush (i_in) +end diff --git a/pkg/images/tv/iis/ids/idsinit.x b/pkg/images/tv/iis/ids/idsinit.x new file mode 100644 index 00000000..7ac925a3 --- /dev/null +++ b/pkg/images/tv/iis/ids/idsinit.x @@ -0,0 +1,172 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <ctype.h> +include <gki.h> +include "../lib/ids.h" + +# IDS_INIT -- Initialize the ids data structures from the graphcap entry +# for the device. Called once, at OPENWS time, with the TTY pointer already +# set in the common. + +procedure ids_init (tty, devname) + +pointer tty # graphcap descriptor +char devname[ARB] # device name + +pointer nextch +int maxch, i +real char_height, char_width, char_size + +bool ttygetb() +real ttygetr() +int ttygeti(), btoi(), gstrcpy() + +include "../lib/ids.com" + +begin + # Allocate the ids descriptor and the string buffer. + if ( i_kt == NULL) { + call calloc (i_kt, LEN_IDS, TY_STRUCT) + call malloc (IDS_SBUF(i_kt), SZ_SBUF, TY_CHAR) + call malloc (IDS_BITPL(i_kt), IDS_MAXBITPL+1, TY_SHORT) + } else { + call mfree (IDS_FRAME(i_kt), TY_SHORT) + } + + + # Init string buffer parameters. The first char of the string buffer + # is reserved as a null string, used for graphcap control strings + # omitted from the graphcap entry for the device. + + IDS_SZSBUF(i_kt) = SZ_SBUF + IDS_NEXTCH(i_kt) = IDS_SBUF(i_kt) + 1 + Memc[IDS_SBUF(i_kt)] = EOS + + # get the device resolution from the graphcap entry. + + i_xres = ttygeti (tty, "xr") + if (i_xres <= 0) + i_xres = 512 + i_yres = ttygeti (tty, "yr") + if (i_yres <= 0) + i_yres = 512 + + + # Initialize the character scaling parameters, required for text + # generation. The heights are given in NDC units in the graphcap + # file, which we convert to GKI units. Estimated values are + # supplied if the parameters are missing in the graphcap entry. + + char_height = ttygetr (tty, "ch") + if (char_height < EPSILON) + char_height = 1.0 / 35.0 + char_height = char_height * GKI_MAXNDC + + char_width = ttygetr (tty, "cw") + if (char_width < EPSILON) + char_width = 1.0 / 80.0 + char_width = char_width * GKI_MAXNDC + + # If the device has a set of discreet character sizes, get the + # size of each by fetching the parameter "tN", where the N is + # a digit specifying the text size index. Compute the height and + # width of each size character from the "ch" and "cw" parameters + # and the relative scale of character size I. + + IDS_NCHARSIZES(i_kt) = min (MAX_CHARSIZES, ttygeti (tty, "th")) + nextch = IDS_NEXTCH(i_kt) + + if (IDS_NCHARSIZES(i_kt) <= 0) { + IDS_NCHARSIZES(i_kt) = 1 + IDS_CHARSIZE(i_kt,1) = 1.0 + IDS_CHARHEIGHT(i_kt,1) = char_height + IDS_CHARWIDTH(i_kt,1) = char_width + } else { + Memc[nextch+2] = EOS + for (i=1; i <= IDS_NCHARSIZES(i_kt); i=i+1) { + Memc[nextch] = 't' + Memc[nextch+1] = TO_DIGIT(i) + char_size = ttygetr (tty, Memc[nextch]) + IDS_CHARSIZE(i_kt,i) = char_size + IDS_CHARHEIGHT(i_kt,i) = char_height * char_size + IDS_CHARWIDTH(i_kt,i) = char_width * char_size + } + } + + # Initialize the output parameters. All boolean parameters are stored + # as integer flags. All string valued parameters are stored in the + # string buffer, saving a pointer to the string in the ids + # descriptor. If the capability does not exist the pointer is set to + # point to the null string at the beginning of the string buffer. + + IDS_POLYLINE(i_kt) = btoi (ttygetb (tty, "pl")) + IDS_POLYMARKER(i_kt) = btoi (ttygetb (tty, "pm")) + IDS_FILLAREA(i_kt) = btoi (ttygetb (tty, "fa")) + IDS_FILLSTYLE(i_kt) = ttygeti (tty, "fs") + IDS_ROAM(i_kt) = btoi (ttygetb (tty, "ro")) + IDS_CANZM(i_kt) = btoi (ttygetb (tty, "zo")) + IDS_ZRES(i_kt) = ttygeti (tty, "zr") + IDS_CELLARRAY(i_kt) = btoi (ttygetb (tty, "ca")) + IDS_SELERASE(i_kt) = btoi (ttygetb (tty, "se")) + + # how many image frames and graph (bit)planes do we get to play with? + + i_maxframes = ttygeti(tty, "ip") + if ( i_maxframes < 1 ) + i_maxframes = 1 + i_maxgraph = ttygeti(tty, "gp") + i_maxframes = min(int(i_maxframes), IDS_MAXIMPL) + i_maxgraph = min(int(i_maxgraph), IDS_MAXGRPL) + + # allocate space for the frame descriptors + # the "2" accounts for possible graphics channel ( see ids_expand.x) + # and the trailing IDS_EOD + + call malloc (IDS_FRAME(i_kt), max(i_maxframes,i_maxgraph)+2, TY_SHORT) + + # Initialize the input parameters: last cursor used. + + IDS_LCURSOR(i_kt) = 1 + + # Save the device string in the descriptor. + nextch = IDS_NEXTCH(i_kt) + IDS_DEVNAME(i_kt) = nextch + maxch = IDS_SBUF(i_kt) + SZ_SBUF - nextch + 1 + nextch = nextch + gstrcpy (devname, Memc[nextch], maxch) + 1 + IDS_NEXTCH(i_kt) = nextch + +end + + +# IDS_GSTRING -- Get a string value parameter from the graphcap table, +# placing the string at the end of the string buffer. If the device does +# not have the named capability return a pointer to the null string, +# otherwise return a pointer to the string. Since pointers are used, +# rather than indices, the string buffer is fixed in size. The additional +# degree of indirection required with an index was not considered worthwhile +# in this application since the graphcap entries are never very large. + +pointer procedure ids_gstring (cap) + +char cap[ARB] # device capability to be fetched +pointer strp, nextch +int maxch, nchars +int ttygets() + +include "../lib/ids.com" + +begin + nextch = IDS_NEXTCH(i_kt) + maxch = IDS_SBUF(i_kt) + SZ_SBUF - nextch + 1 + + nchars = ttygets (i_tty, cap, Memc[nextch], maxch) + if (nchars > 0) { + strp = nextch + nextch = nextch + nchars + 1 + } else + strp = IDS_SBUF(i_kt) + + IDS_NEXTCH(i_kt) = nextch + return (strp) +end diff --git a/pkg/images/tv/iis/ids/idsline.x b/pkg/images/tv/iis/ids/idsline.x new file mode 100644 index 00000000..ecc63d8c --- /dev/null +++ b/pkg/images/tv/iis/ids/idsline.x @@ -0,0 +1,30 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <gset.h> +include "../lib/ids.h" + +# IDS_LINE set the line type option in the nspp world + +procedure ids_line(index) + +int index # index for line type switch statement + +int linetype + +include "../lib/ids.com" + +begin + switch (index) { + case GL_CLEAR: + linetype = 0 + case GL_DASHED: + linetype = 0FF00X + case GL_DOTTED: + linetype = 08888X + case GL_DOTDASH: + linetype = 0F040X + default: + linetype = 0FFFFX # GL_SOLID and default + } + i_linemask = linetype +end diff --git a/pkg/images/tv/iis/ids/idslutfill.x b/pkg/images/tv/iis/ids/idslutfill.x new file mode 100644 index 00000000..be42c774 --- /dev/null +++ b/pkg/images/tv/iis/ids/idslutfill.x @@ -0,0 +1,36 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <gki.h> + +# IDSLUTFILL -- Fill a lookup table from a set of line end points + +procedure idslfill (in, icount, out, lenlut, lutmin, lutmax) + +short in[ARB] # input: line end points +int icount # number of input data items +short out[ARB] # output: the lookup table +int lenlut # lut size +int lutmin,lutmax # inclusive range for lut values + +int i,j +int xs, ys, xe, ye +real slope + +begin + # xs and xe are zero based coordinates + xs = real(in[1]) * (lenlut - 1)/GKI_MAXNDC. + 0.5 + ys = real(in[2]) * (lutmax - lutmin)/GKI_MAXNDC. + lutmin + 0.5 + do i = 3, icount, 2 { + xe = real(in[i]) * (lenlut - 1)/GKI_MAXNDC. + 0.5 + ye = real(in[i+1]) * (lutmax - lutmin)/GKI_MAXNDC. + lutmin + 0.5 + if (xe != xs) { + slope = real(ye - ys) / (xe - xs) + do j = xs, xe { + out[j+1] = ys + (j - xs) * slope + } + } + xs = xe + ys = ye + } + out[1] = 0 # keep background at zero +end diff --git a/pkg/images/tv/iis/ids/idsopen.x b/pkg/images/tv/iis/ids/idsopen.x new file mode 100644 index 00000000..cee1aebe --- /dev/null +++ b/pkg/images/tv/iis/ids/idsopen.x @@ -0,0 +1,58 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <gki.h> +include "../lib/ids.h" + +# IDS_OPEN -- Install the image kernel as a kernel device driver. +# The device table DD consists of an array of the entry point addresses for +# the driver procedures. If a driver does not implement a particular +# instruction the table entry for that procedure may be set to zero, causing +# the interpreter to ignore the instruction. + +procedure ids_open (devname, dd) + +char devname[ARB] # nonnull for forced output to device +int dd[ARB] # device table to be initialized + +int locpr() +extern ids_openws(), ids_closews(), ids_clear(), ids_cancel() +extern ids_flush(), ids_polyline(), ids_polymarker(), ids_text() +extern ids_fillarea(), ids_putcellarray(), ids_plset() +extern ids_pmset(), ids_txset(), ids_faset() +extern ids_escape() +extern ids_setcursor(), ids_getcursor(), ids_getcellarray() + +include "../lib/ids.com" + +begin + # Flag first pass. Save forced device name in common for OPENWS. + + i_kt = NULL + call strcpy (devname, i_device, SZ_IDEVICE) + + # Install the device driver. + dd[GKI_OPENWS] = locpr (ids_openws) + dd[GKI_CLOSEWS] = locpr (ids_closews) + dd[GKI_DEACTIVATEWS] = 0 + dd[GKI_REACTIVATEWS] = 0 + dd[GKI_MFTITLE] = 0 + dd[GKI_CLEAR] = locpr (ids_clear) + dd[GKI_CANCEL] = locpr (ids_cancel) + dd[GKI_FLUSH] = locpr (ids_flush) + dd[GKI_POLYLINE] = locpr (ids_polyline) + dd[GKI_POLYMARKER] = locpr (ids_polymarker) + dd[GKI_TEXT] = locpr (ids_text) + dd[GKI_FILLAREA] = locpr (ids_fillarea) + dd[GKI_PUTCELLARRAY] = locpr (ids_putcellarray) + dd[GKI_SETCURSOR] = locpr (ids_setcursor) + dd[GKI_PLSET] = locpr (ids_plset) + dd[GKI_PMSET] = locpr (ids_pmset) + dd[GKI_TXSET] = locpr (ids_txset) + dd[GKI_FASET] = locpr (ids_faset) + dd[GKI_GETCURSOR] = locpr (ids_getcursor) + dd[GKI_GETCELLARRAY] = locpr (ids_getcellarray) + dd[GKI_ESCAPE] = locpr (ids_escape) + dd[GKI_SETWCS] = 0 + dd[GKI_GETWCS] = 0 + dd[GKI_UNKNOWN] = 0 +end diff --git a/pkg/images/tv/iis/ids/idsopenws.x b/pkg/images/tv/iis/ids/idsopenws.x new file mode 100644 index 00000000..bd25b260 --- /dev/null +++ b/pkg/images/tv/iis/ids/idsopenws.x @@ -0,0 +1,120 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <fset.h> +include <gki.h> +include <error.h> +include "../lib/ids.h" + +# IDS_OPENWS -- Open the named workstation. Once a workstation has been +# opened we leave it open until some other workstation is opened or the +# kernel is closed. Opening a workstation involves initialization of the +# kernel data structures. Initialization of the device itself is left to +# an explicit reset command. + +procedure ids_openws (devname, n, mode) + +short devname[ARB] # device name +int n # length of device name +int mode # access mode + +long filesize +bool need_open, same_dev +pointer sp, buf, devinfo + +long fstatl() +pointer ttygdes() +bool streq(), ttygetb() +int fopnbf(), ttygets() +extern zopnim(), zardim(), zawrim(), zawtim(), zsttim(), zclsim() +errchk ttygdes +int oldmode +data oldmode /-1/ + +include "../lib/ids.com" + +begin + call smark (sp) + call salloc (buf, max (SZ_FNAME, n), TY_CHAR) + call salloc (devinfo, SZ_LINE, TY_CHAR) + + # If a device was named when the kernel was opened then output will + # always be to that device (i_device) regardless of the device named + # in the OPENWS instruction. If no device was named (null string) + # then unpack the device name, passed as a short integer array. + + if (i_device[1] == EOS) { + call achtsc (devname, Memc[buf], n) + Memc[buf+n] = EOS + } else + call strcpy (i_device, Memc[buf], SZ_FNAME) + + # find out if first time, and if not, if same device as before + # note that if (i_kt == NULL), then same_dev is false. + + same_dev = false + need_open = true + if ( i_kt != NULL ) { + same_dev = (streq(Memc[IDS_DEVNAME(i_kt)], Memc[buf])) + if ( !same_dev || ( oldmode != mode)) + call close(i_out) + else + need_open = false + } + oldmode = mode + + # Initialize the kernel data structures. Open graphcap descriptor + # for the named device, allocate and initialize descriptor and common. + # graphcap entry for device must exist. + + if (need_open) { + if ((i_kt != NULL) && !same_dev) + call ttycdes (i_tty) + if (!same_dev) { + i_tty = ttygdes (Memc[buf]) + if (ttygetb (i_tty, "LC")) + call error (1, "operation not supported on device") + } + + if (ttygets (i_tty, "DD", Memc[devinfo], SZ_LINE) <= 0) + call strcpy (Memc[buf], Memc[devinfo], SZ_LINE) + + # Open the output file. The device is connected to FIO as a + # binary file. mode must be READ_WRITE or WRITE_ONLY + # for image display! + + iferr (i_out = fopnbf (Memc[devinfo], mode, zopnim, zardim, + zawrim, zawtim, zsttim, zclsim)) { + + call ttycdes (i_tty) + call erract (EA_ERROR) + } + call fseti (i_out, F_ADVICE, SEQUENTIAL) + + } + + # Initialize data structures. + # Device specific initialization will be done in the zinit call + # from ids_init(). + + if (!same_dev) { + call ids_init (i_tty, Memc[buf]) + + # Now set the file size to allow mapping of all control registers + # as well as all image and graphics planes. The call to fstatl + # returns the size of an image plane (!!). zinit does whatever + # device work it needs to do, and uses its arguments to determine + # the total file size, which it returns. + # This feature need not be used (and is not for the IIS display). + # + # We also set the F_ASYNC parameter to YES. + + i_frsize = fstatl(i_out, F_FILESIZE) + filesize = i_frsize + call zinit(i_maxframes, i_maxgraph, filesize) + call fseti(i_out, F_ASYNC, YES) + + } + + call sfree (sp) +end diff --git a/pkg/images/tv/iis/ids/idspcell.x b/pkg/images/tv/iis/ids/idspcell.x new file mode 100644 index 00000000..d678b286 --- /dev/null +++ b/pkg/images/tv/iis/ids/idspcell.x @@ -0,0 +1,178 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <gki.h> +include <gset.h> +include "../lib/ids.h" + +# number of grey scale symbols +define NSYMBOL 11 +define TSIZE (1.0/2.0) + +# IDS_PUTCELLARRAY -- Draw a cell array, i.e., two dimensional array of pixels +# (greylevels or colors). + +procedure ids_putcellarray (m, nc, nr, ax1,ay1, ax2,ay2) + +short m[ARB] # cell array +int nc, nr # number of pixels in X and Y + # (number of columns[x], rows[y] +int ax1, ay1 # lower left corner of output window +int ax2, ay2 # upper right corner of output window + +int x1,y1,x2,y2 +real px1, py1, px2, py2 +int nx, ny +real skip_x, skip_y, sx, sy +real blockx, blocky, bcy +int i, j, startrow, element +real xres, yres +pointer sp, cell +bool ca, use_orig, new_row + +include "../lib/ids.com" + +begin + # determine if can do real cell array. + + ca = (IDS_CELLARRAY(i_kt) != 0) + if ( !ca ) + return + + skip_x = 1.0 + skip_y = 1.0 + blockx = 1.0 + blocky = 1.0 + + xres = real(i_xres) + yres = real(i_yres) + + # adjust pixels for edges + x1 = ax1 + x2 = ax2 + y1 = ay1 + y2 = ay2 + call ids_cround(x1,x2,xres) + call ids_cround(y1,y2,yres) + + # find out how many real pixels we have to fill + + px1 = real(x1) * xres /(GKI_MAXNDC+1) + py1 = real(y1) * yres /(GKI_MAXNDC+1) + px2 = real(x2) * xres /(GKI_MAXNDC+1) + py2 = real(y2) * yres /(GKI_MAXNDC+1) + + nx = int( px2 ) - int( px1 ) + 1 + ny = int( py2 ) - int( py1 ) + 1 + + # if too many data points in input, set skip. If skip is close + # enough to one, set it to one. + # set block replication factors - will be > 1.0 if too few input points. + # cannot set to 1.0 if "close" enough, since, if > 1.0, we don't have + # enough points and so *some* have to be replicated. + + if ( nc > nx ) { + skip_x = real(nc)/nx + if ( (skip_x - 1.0)*(nx-1) < 1.0 ) + skip_x = 1.0 + } else + blockx = real(nx)/nc + + if ( nr > ny ) { + skip_y = real(nr)/ny + if ( (skip_y - 1.0)*(ny-1) < 1.0 ) + skip_y = 1.0 + } else + blocky = real(ny)/nr + + # initialize counters + + call smark(sp) + sy = skip_y + bcy = blocky + startrow = 1 + element = startrow + + # see if we can use original data ... no massaging + # also set the initial value of the new_row flag, which tells + # if we have to rebuild the row data + # note that if blockx > 1.0, skip_x must be 1.0, and vv + + if ( (skip_x == 1.0) && (blockx == 1.0) ) { + use_orig = true + new_row = false + } else { + use_orig = false + new_row = true + # allocate storage for a row of pixels. + call salloc ( cell, nx, TY_SHORT) + } + + # do it + + for ( i = 1; i <= ny ; i = i + 1) { + + # Build the row data. + + if (!use_orig && new_row) { + if ( skip_x == 1.0) + call ids_blockit(m[element], Mems[cell], nx, blockx) + else { + sx = skip_x + for ( j = 1; j <= nx; j = j + 1) { + Mems[cell+j-1] = m[element] + element = startrow + int(sx+0.5) + sx = sx + skip_x + } + } + } + + # Send the row data. The writing routine will figure out + # how to send to the various individual frames and bitplanes. + + call zseek (i_out, int(px1), int(py1)+i-1) + if (use_orig) + call write (i_out, m[element], nx) + else + call write (i_out, Mems[cell], nx) + + # Advance a row. + + element = startrow + if ( bcy <= real(i) ) { + startrow = 1 + nc * int(sy+0.5) + element = startrow + sy = sy + skip_y + bcy = bcy + blocky + new_row = true + } else { + new_row = false + } + } + + call sfree(sp) +end + + +# IDS_BLOCKIT -- block replication of data + +procedure ids_blockit( from, to, count, factor) + +short from[ARB] # input data +short to[ARB] # output data +int count # number of output pixels +real factor # blocking factor + +int i, j +real bc + +begin + bc = factor + j = 1 + for ( i = 1; i <= count ; i = i + 1 ) { + to[i] = from[j] + if ( bc <= real(i) ) { + j = j + 1 + bc = bc + factor + } + } +end diff --git a/pkg/images/tv/iis/ids/idspl.x b/pkg/images/tv/iis/ids/idspl.x new file mode 100644 index 00000000..77ac3bc3 --- /dev/null +++ b/pkg/images/tv/iis/ids/idspl.x @@ -0,0 +1,61 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <gki.h> +include "../lib/ids.h" + +# nspp particulars +# base width of line +define BASELW 8 + +# IDS_POLYLINE -- Draw a polyline. The polyline is defined by the array of +# points P, consisting of successive (x,y) coordinate pairs. The first point +# is not plotted but rather defines the start of the polyline. The remaining +# points define line segments to be drawn. + +procedure ids_polyline (p, npts) + +short p[ARB] # points defining line +int npts # number of points, i.e., (x,y) pairs + +pointer pl +int i, len_p +int linewidth + +include "../lib/ids.com" + +begin + if ( npts <= 0) + return + + len_p = npts * 2 + + # Update polyline attributes if necessary. + + pl = IDS_PLAP(i_kt) + + if (IDS_TYPE(i_kt) != PL_LTYPE(pl)) { + call ids_line(PL_LTYPE(pl)) + IDS_TYPE(i_kt) = PL_LTYPE(pl) + } + if (IDS_WIDTH(i_kt) != PL_WIDTH(pl)) { + linewidth = int(real(BASELW) * GKI_UNPACKREAL(PL_WIDTH(pl))) + i_linewidth = max(1,linewidth) + IDS_WIDTH(i_kt) = PL_WIDTH(pl) + } + if (IDS_COLOR(i_kt) != PL_COLOR(pl)) { + i_linecolor = PL_COLOR(pl) + IDS_COLOR(i_kt) = PL_COLOR(pl) + } + + # Move to the first point. point() will plot it, which is + # ok here, and vector may well plot it again. + + call ids_point(p[1], p[2], true) + + # Draw the polyline. + + for (i=3; i <= len_p; i=i+2) { + call ids_vector ( p[i], p[i+1]) + + } +end diff --git a/pkg/images/tv/iis/ids/idsplset.x b/pkg/images/tv/iis/ids/idsplset.x new file mode 100644 index 00000000..cf49ea1f --- /dev/null +++ b/pkg/images/tv/iis/ids/idsplset.x @@ -0,0 +1,21 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <gki.h> +include "../lib/ids.h" + +# IDS_PLSET -- Set the polyline attributes. The polyline width parameter is +# passed to the encoder as a packed floating point number, i.e., int(LWx100). + +procedure ids_plset (gki) + +short gki[ARB] # attribute structure +pointer pl + +include "../lib/ids.com" + +begin + pl = IDS_PLAP(i_kt) + PL_LTYPE(pl) = gki[GKI_PLSET_LT] + PL_WIDTH(pl) = gki[GKI_PLSET_LW] + PL_COLOR(pl) = gki[GKI_PLSET_CI] +end diff --git a/pkg/images/tv/iis/ids/idspm.x b/pkg/images/tv/iis/ids/idspm.x new file mode 100644 index 00000000..b165b7cc --- /dev/null +++ b/pkg/images/tv/iis/ids/idspm.x @@ -0,0 +1,56 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <gki.h> +include "../lib/ids.h" + +# nspp particulars +# base width of line +define BASELW 8 + +# IDS_POLYMARKER -- Draw a polymarker. The polymarker is defined by the array +# of points P, consisting of successive (x,y) coordinate pairs. The first point +# is not plotted but rather defines the start of the polyline. The remaining +# points define line segments to be drawn. + +procedure ids_polymarker (p, npts) + +short p[ARB] # points defining line +int npts # number of points, i.e., (x,y) pairs + +pointer pm +int i, len_p +int linewidth +short x,y + +include "../lib/ids.com" + +begin + if ( npts <= 0) + return + + len_p = npts * 2 + + # Update polymarker attributes if necessary. + + pm = IDS_PMAP(i_kt) + + if (IDS_TYPE(i_kt) != PM_LTYPE(pm)) { + call ids_line(PM_LTYPE(pm)) + IDS_TYPE(i_kt) = PM_LTYPE(pm) + } + if (IDS_WIDTH(i_kt) != PM_WIDTH(pm)) { + linewidth = int(real(BASELW) * GKI_UNPACKREAL(PM_WIDTH(pm))) + i_linewidth = max(1,linewidth) + IDS_WIDTH(i_kt) = PM_WIDTH(pm) + } + if (IDS_COLOR(i_kt) != PM_COLOR(pm)) { + i_linecolor = PM_COLOR(pm) + IDS_COLOR(i_kt) = PM_COLOR(pm) + } + + for (i=1; i <= len_p; i=i+2) { + x = p[i] + y = p[i+1] + call ids_point (real(x)/GKI_MAXNDC, real(y)/GKI_MAXNDC, true) + } +end diff --git a/pkg/images/tv/iis/ids/idspmset.x b/pkg/images/tv/iis/ids/idspmset.x new file mode 100644 index 00000000..be46ede8 --- /dev/null +++ b/pkg/images/tv/iis/ids/idspmset.x @@ -0,0 +1,19 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <gki.h> +include "../lib/ids.h" + +# IDS_PMSET -- Set the polymarker attributes. + +procedure ids_pmset (gki) + +short gki[ARB] # attribute structure +pointer pm +include "../lib/ids.com" + +begin + pm = IDS_PMAP(i_kt) + PM_LTYPE(pm) = gki[GKI_PMSET_MT] + PM_WIDTH(pm) = gki[GKI_PMSET_MW] + PM_COLOR(pm) = gki[GKI_PMSET_CI] +end diff --git a/pkg/images/tv/iis/ids/idspoint.x b/pkg/images/tv/iis/ids/idspoint.x new file mode 100644 index 00000000..2addb635 --- /dev/null +++ b/pkg/images/tv/iis/ids/idspoint.x @@ -0,0 +1,65 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <gki.h> +include <fset.h> +include "../lib/ids.h" + +# IDS_POINT -- Plot a point in the current plane at given (GKI) coordinates. + +procedure ids_point (ax,ay,flag) + +short ax,ay # point coordinates, GKI +bool flag # true if should plot point, false if just a + # pen move +int xp, yp +int bufsize +int fstati() + +include "../lib/ids.com" + +begin + # convert to device coords, plot max value, then record in i_pt + xp = real(ax) * i_xres /(GKI_MAXNDC+1) + yp = real(ay) * i_yres /(GKI_MAXNDC+1) + + # if flag is true, we plot the point. If false, we just want + # to record the points (a pen move), so skip the plot commands + + if (flag) { + # set buffer to size one + bufsize = fstati (i_out, F_BUFSIZE) + call fseti (i_out, F_BUFSIZE, 1) + + # plot it + call zseek (i_out, xp, yp) + call write(i_out, short(IDS_ZRES(i_kt)-1), 1) + + # restore buffer + call fseti (i_out, F_BUFSIZE, bufsize) + } + i_pt_x = xp + i_pt_y = yp +end + + +# IDS_RPOINT - Plot a point in the current plane at given (device coord) offsets +# from current point. + +procedure ids_rpoint (dx,dy) + +short dx,dy # DEVICE coordinate increments from cur. pos. + +int xp, yp + +include "../lib/ids.com" + +begin + xp = i_pt_x + dx + yp = i_pt_y + dy + + call zseek (i_out, xp, yp) + call write(i_out, short(IDS_ZRES(i_kt)-1), 1) + + i_pt_x = xp + i_pt_y = yp +end diff --git a/pkg/images/tv/iis/ids/idsreset.x b/pkg/images/tv/iis/ids/idsreset.x new file mode 100644 index 00000000..627b3d4e --- /dev/null +++ b/pkg/images/tv/iis/ids/idsreset.x @@ -0,0 +1,56 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <gki.h> +include <gset.h> +include "../lib/ids.h" + +# IDS_RESET -- Reset the state of the transform common, i.e., in response to +# a clear or a cancel. Initialize all attribute packets to their default +# values and set the current state of the device to undefined, forcing the +# device state to be reset when the next output instruction is executed. +# Clear the image, graphics, and luts only if reset is "hard" enough. + +procedure ids_reset(hardness) + +short hardness + +pointer pl, pm, fa, tx + +include "../lib/ids.com" + +begin + # Set pointers to attribute substructures. + pl = IDS_PLAP(i_kt) + pm = IDS_PMAP(i_kt) + fa = IDS_FAAP(i_kt) + tx = IDS_TXAP(i_kt) + + # Initialize the attribute packets. + PL_LTYPE(pl) = 1 + PL_WIDTH(pl) = GKI_PACKREAL(1.) + PL_COLOR(pl) = 1 + PM_LTYPE(pm) = 1 + PM_WIDTH(pm) = GKI_PACKREAL(1.) + PM_COLOR(pm) = 1 + FA_STYLE(fa) = 1 + FA_COLOR(fa) = 1 + TX_UP(tx) = 90 + TX_SIZE(tx) = GKI_PACKREAL(1.) + TX_PATH(tx) = GT_RIGHT + TX_HJUSTIFY(tx) = GT_LEFT + TX_VJUSTIFY(tx) = GT_BOTTOM + TX_FONT(tx) = GT_ROMAN + TX_COLOR(tx) = 1 + TX_SPACING(tx) = 0.0 + + # Set the device attributes to undefined, forcing them to be reset + # when the next output instruction is executed. + + IDS_TYPE(i_kt) = -1 + IDS_WIDTH(i_kt) = -1 + IDS_COLOR(i_kt) = -1 + IDS_TXSIZE(i_kt) = -1 + IDS_TXFONT(i_kt) = -1 + + call zreset(hardness) +end diff --git a/pkg/images/tv/iis/ids/idsrestore.x b/pkg/images/tv/iis/ids/idsrestore.x new file mode 100644 index 00000000..246631c0 --- /dev/null +++ b/pkg/images/tv/iis/ids/idsrestore.x @@ -0,0 +1,84 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../lib/ids.h" + +# IDS_RESTORE -- Restore the control state of the display, together with +# zero to all of the image and graphics planes. + +procedure ids_restore (data, n) + +short data[ARB] # instruction data words +short n # number of data words + +int fd # binary file output descriptor +short i, j +short frame[IDS_MAXIMPL+1] # frames to save +short graph[IDS_MAXGRPL+1] # graph planes to save +short buffer[IDS_MAXDATA] # for data storage + +include "../lib/ids.com" + +begin + # determine file descriptor to read (opened by upper end) + # ( assume upper end has retrieved whatever data it stored and + # leaves fd pointing at control information offset) + # then retrieve the frame data + + fd = data[1] + + # image data + + call read(fd, i, SZ_SHORT) + call read(fd, buffer, i) + j = 0 + i = 0 + repeat { + i = i + 1 + j = j + 1 + frame[j] = buffer[i] + } until ( (buffer[i] == IDS_EOD) || ( j == i_maxframes) ) + frame[i+1] = IDS_EOD + + # graph data + + call read(fd, i, SZ_SHORT) + call read(fd, buffer, i) + i = 0 + j = 0 + repeat { + i = i + 1 + j = j + 1 + graph[j] = buffer[i] + } until ( (buffer[i] == IDS_EOD) || ( j == i_maxgraph) ) + graph[i+1] = IDS_EOD + + # get all control information + + call zdev_restore(fd) + + # get image data + + if ( frame[1] == IDS_EOD) { + for ( i = 1 ; i <= i_maxframes ; i = i + 1) + frame[i] = i + frame[i+1] = IDS_EOD + } + if ( frame[1] != 0 ) { + for ( i = 1 ; frame[i] != IDS_EOD ; i = i + 1) + call zim_restore (fd, frame[i]) + } + + # get graphics data + + if ( graph[1] == IDS_EOD) { + for ( i = 1 ; i <= i_maxgraph ; i = i + 1) + graph[i] = i + graph[i+1] = IDS_EOD + } + if ( graph[1] != 0 ) { + for ( i = 1 ; graph[i] != IDS_EOD ; i = i + 1) + call zgr_restore (fd, graph[i]) + } + + # upper end to close file +end diff --git a/pkg/images/tv/iis/ids/idssave.x b/pkg/images/tv/iis/ids/idssave.x new file mode 100644 index 00000000..a66ebc00 --- /dev/null +++ b/pkg/images/tv/iis/ids/idssave.x @@ -0,0 +1,82 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../lib/ids.h" + +# IDS_SAVE -- Save the control state of the display, together with +# zero to all of the image and graphics planes. + +procedure ids_save (data, n) + +short data[ARB] # instruction data words +short n # count of data words + +int fd # binary file output descriptor +short i, j +short frame[IDS_MAXIMPL+1] # frames to save +short graph[IDS_MAXGRPL+1] # graph planes to save + +include "../lib/ids.com" + +begin + # do we need to check n ?? + + # determine file descriptor to write (opened by upper end) + # ( assume upper end has saved whatever data it wanted and + # leaves fd pointing at control information offset) + # then squirrel away the frame data + + fd = data[1] + + # image data + + i = 1 + j = 0 + repeat { + i = i + 1 + j = j + 1 + frame[j] = data[i] + } until ( data[i] == IDS_EOD ) + call write(fd, j, SZ_SHORT) + call write(fd, frame[1], j*SZ_SHORT) + + # graph data + + j = 0 + repeat { + i = i + 1 + j = j + 1 + graph[j] = data[i] + } until ( data[i] == IDS_EOD ) + call write(fd, j, SZ_SHORT) + call write(fd, graph[1], j*SZ_SHORT) + + # get all control information + + call zdev_save(fd) + + # get image data + + if ( frame[1] == IDS_EOD) { + for ( i = 1 ; i <= i_maxframes ; i = i + 1) + frame[i] = i + frame[i+1] = IDS_EOD + } + if ( frame[1] != 0 ) { + for ( i = 1 ; frame[i] != IDS_EOD ; i = i + 1) + call zim_save (fd, frame[i]) + } + + # get graphics data + + if ( graph[1] == IDS_EOD) { + for ( i = 1 ; i <= i_maxgraph ; i = i + 1) + graph[i] = i + graph[i+1] = IDS_EOD + } + if ( graph[1] != 0 ) { + for ( i = 1 ; graph[i] != IDS_EOD ; i = i + 1) + call zgr_save (fd, graph[i]) + } + + # upper end to close file +end diff --git a/pkg/images/tv/iis/ids/idsscur.x b/pkg/images/tv/iis/ids/idsscur.x new file mode 100644 index 00000000..7ec48c32 --- /dev/null +++ b/pkg/images/tv/iis/ids/idsscur.x @@ -0,0 +1,12 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +# IDS_SETCURSOR -- Set the position of a cursor. + +procedure ids_setcursor (x, y, cursor) + +int x, y # new position of cursor +int cursor # cursor to be set + +begin + call zcursor_set(cursor, x, y) +end diff --git a/pkg/images/tv/iis/ids/idsstream.x b/pkg/images/tv/iis/ids/idsstream.x new file mode 100644 index 00000000..bb7360b4 --- /dev/null +++ b/pkg/images/tv/iis/ids/idsstream.x @@ -0,0 +1,16 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../lib/ids.h" + +# IDS_GRSTREAM -- Set the FD of the graphics/image stream, to which +# we return cell arrays and cursor values. + +procedure ids_grstream (stream) + +int stream + +include "../lib/ids.com" + +begin + i_in = stream +end diff --git a/pkg/images/tv/iis/ids/idstx.x b/pkg/images/tv/iis/ids/idstx.x new file mode 100644 index 00000000..7209d00b --- /dev/null +++ b/pkg/images/tv/iis/ids/idstx.x @@ -0,0 +1,428 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <math.h> +include <gset.h> +include <gki.h> +include "../lib/ids.h" + +define BASECS_X 12 # Base (size 1.0) char width in GKI coords. +define BASECS_Y 12 # Base (size 1.0) char height in GKI coords. + + +# IDS_TEXT -- Draw a text string. The string is drawn at the position (X,Y) +# using the text attributes set by the last GKI_TXSET instruction. The text +# string to be drawn may contain embedded set font escape sequences of the +# form \fR (roman), \fG (greek), etc. We break the input text sequence up +# into segments at font boundaries and draw these on the output device, +# setting the text size, color, font, and position at the beginning of each +# segment. + +procedure ids_text (xc, yc, text, n) + +int xc, yc # where to draw text string +short text[ARB] # text string +int n # number of characters + +real x, y, dx, dy, tsz +int x1, x2, y1, y2, orien +int x0, y0, ids_dx, ids_dy, ch, cw +int xstart, ystart, newx, newy +int totlen, polytext, font, seglen +pointer sp, seg, ip, op, tx, first +int stx_segment() + +include "../lib/ids.com" + +real i_dx, i_dy # scale GKI to window coords +int i_x1, i_y1 # origin of device window +int i_x2, i_y2 # upper right corner of device window +data i_dx /1.0/, i_dy /1.0/ +data i_x1 /0/, i_y1 /0/, i_x2 /GKI_MAXNDC/, i_y2 / GKI_MAXNDC/ + +begin + call smark (sp) + call salloc (seg, n + 2, TY_CHAR) + + # Set pointer to the text attribute structure. + tx = IDS_TXAP(i_kt) + + # Set the text size and color if not already set. Both should be + # invalidated when the screen is cleared. Text color should be + # invalidated whenever another color is set. The text size was + # set by ids_txset, and is just a scaling factor. + + IDS_TXSIZE(i_kt) = TX_SIZE(tx) + # For display, have 32767 sizes, so just scale the the base sizes. + tsz = GKI_UNPACKREAL(TX_SIZE(tx)) # scale factor + ch = IDS_CHARHEIGHT(i_kt,1) * tsz + cw = IDS_CHARWIDTH(i_kt,1) * tsz + + if (TX_COLOR(tx) != IDS_COLOR(i_kt)) { + # Should do something like call ids_color (TX_COLOR(tx)) + # But that requires some association of color with hardware + # and what that should be is not clear. + IDS_COLOR(i_kt) = TX_COLOR(tx) + } + + # Set the linetype to a solid line, and invalidate last setting. + call ids_linetype (GL_SOLID) + IDS_TYPE(i_kt) = -1 + + # Break the text string into segments at font boundaries and count + # the total number of printable characters. + + totlen = stx_segment (text, n, Memc[seg], TX_FONT(tx)) + + # Compute the text drawing parameters, i.e., the coordinates of the + # first character to be drawn, the step between successive characters, + # and the polytext flag (GKI coords). + + call stx_parameters (xc,yc, totlen, x0,y0, ids_dx,ids_dy, polytext, + orien) + + # Draw the segments, setting the font at the beginning of each segment. + # The first segment is drawn at (X0,Y0). The separation between + # characters is DX,DY. A segment is drawn as a block if the polytext + # flag is set, otherwise each character is drawn individually. + + x = x0 * i_dx + i_x1 + y = y0 * i_dy + i_y1 + dx = ids_dx * i_dx + dy = ids_dy * i_dy + + for (ip=seg; Memc[ip] != EOS; ip=ip+1) { + # Process the font control character heading the next segment. + font = Memc[ip] + ip = ip + 1 + + # Draw the segment. + while (Memc[ip] != EOS) { + # Clip leading out of bounds characters. + for (; Memc[ip] != EOS; ip=ip+1) { + x1 = x; x2 = x1 + cw + y1 = y; y2 = y1 + ch + + if (x1 >= i_x1 && x2 <= i_x2 && y1 >= i_y1 && y2 <= i_y2) + break + else { + x = x + dx + y = y + dy + } + + if (polytext == NO) { + ip = ip + 1 + break + } + } + + # Coords of first char to be drawn. + xstart = x + ystart = y + + # Move OP to first out of bounds char. + for (op=ip; Memc[op] != EOS; op=op+1) { + x1 = x; x2 = x1 + cw + y1 = y; y2 = y1 + ch + + if (x1 <= i_x1 || x2 >= i_x2 || y1 <= i_y1 || y2 >= i_y2) + break + else { + x = x + dx + y = y + dy + } + + if (polytext == NO) { + op = op + 1 + break + } + } + + # Count number of inbounds chars. + seglen = op - ip + + # Leave OP pointing to the end of this segment. + if (polytext == NO) + op = ip + 1 + else { + while (Memc[op] != EOS) + op = op + 1 + } + + # Compute X,Y of next segment. + newx = xstart + (dx * (op - ip)) + newy = ystart + dy + + # Quit if no inbounds chars. + if (seglen == 0) { + x = newx + y = newy + ip = op + next + } + + # Output the inbounds chars. + + first = ip + x = xstart + y = ystart + + while (seglen > 0 && (polytext == YES || ip == first)) { + call ids_drawchar (Memc[ip], nint(x), nint(y), cw, ch, + orien, font) + ip = ip + 1 + seglen = seglen - 1 + x = x + dx + y = y + dy + } + + x = newx + y = newy + ip = op + } + } + + call sfree (sp) +end + + +# STX_SEGMENT -- Process the text string into segments, in the process +# converting from type short to char. The only text attribute that can +# change within a string is the font, so segments are broken by \fI, \fG, +# etc. font select sequences embedded in the text. The segments are encoded +# sequentially in the output string. The first character of each segment is +# the font number. A segment is delimited by EOS. A font number of EOS +# marks the end of the segment list. The output string is assumed to be +# large enough to hold the segmented text string. + +int procedure stx_segment (text, n, out, start_font) + +short text[ARB] # input text +int n # number of characters in text +char out[ARB] # output string +int start_font # initial font code + +int ip, op +int totlen, font + +begin + out[1] = start_font + totlen = 0 + op = 2 + + for (ip=1; ip <= n; ip=ip+1) { + if (text[ip] == '\\' && text[ip+1] == 'f') { + # Select font. + out[op] = EOS + op = op + 1 + ip = ip + 2 + + switch (text[ip]) { + case 'B': + font = GT_BOLD + case 'I': + font = GT_ITALIC + case 'G': + font = GT_GREEK + default: + font = GT_ROMAN + } + + out[op] = font + op = op + 1 + + } else { + # Deposit character in segment. + out[op] = text[ip] + op = op + 1 + totlen = totlen + 1 + } + } + + # Terminate last segment and add null segment. + + out[op] = EOS + out[op+1] = EOS + + return (totlen) +end + + +# STX_PARAMETERS -- Set the text drawing parameters, i.e., the coordinates +# of the lower left corner of the first character to be drawn, the spacing +# between characters, and the polytext flag. Input consists of the coords +# of the text string, the length of the string, and the text attributes +# defining the character size, justification in X and Y of the coordinates, +# and orientation of the string. All coordinates are in GKI units. + +procedure stx_parameters (xc, yc, totlen, x0, y0, dx, dy, polytext, orien) + +int xc, yc # coordinates at which string is to be drawn +int totlen # number of characters to be drawn +int x0, y0 # lower left corner of first char to be drawn +int dx, dy # step in X and Y between characters +int polytext # OK to output text segment all at once +int orien # rotation angle of characters + +pointer tx +int up, path +real dir, ch, cw, cosv, sinv, space, sz +real xsize, ysize, xvlen, yvlen, xu, yu, xv, yv, p, q + +include "../lib/ids.com" + +begin + tx = IDS_TXAP(i_kt) + + # Get character sizes in GKI coords. + sz = GKI_UNPACKREAL (TX_SIZE(tx)) + ch = IDS_CHARHEIGHT(i_kt,1) * sz + cw = IDS_CHARWIDTH(i_kt,1) * sz + + # Compute the character rotation angle. This is independent of the + # direction in which characters are drawn. A character up vector of + # 90 degrees (normal) corresponds to a rotation angle of zero. + + up = TX_UP(tx) + orien = up - 90 + + # Determine the direction in which characters are to be plotted. + # This depends on both the character up vector and the path, which + # is defined relative to the up vector. + + path = TX_PATH(tx) + switch (path) { + case GT_UP: + dir = up + case GT_DOWN: + dir = up - 180 + case GT_LEFT: + dir = up + 90 + default: # GT_NORMAL, GT_RIGHT + dir = up - 90 + } + + # ------- DX, DY --------- + # Convert the direction vector into the step size between characters. + # Note CW and CH are in GKI coordinates, hence DX and DY are too. + # Additional spacing of some fraction of the character size is used + # if TX_SPACING is nonzero. + + dir = -DEGTORAD(dir) + cosv = cos (dir) + sinv = sin (dir) + + # Correct for spacing (unrotated). + space = (1.0 + TX_SPACING(tx)) + if (path == GT_UP || path == GT_DOWN) + p = ch * space + else + p = cw * space + q = 0 + + # Correct for rotation. + dx = p * cosv + q * sinv + dy = -p * sinv + q * cosv + + # ------- XU, YU --------- + # Determine the coordinates of the center of the first character req'd + # to justify the string, assuming dimensionless characters spaced on + # centers DX,DY apart. + + xvlen = dx * (totlen - 1) + yvlen = dy * (totlen - 1) + + switch (TX_HJUSTIFY(tx)) { + case GT_CENTER: + xu = - (xvlen / 2.0) + case GT_RIGHT: + # If right justify and drawing to the left, no offset req'd. + if (xvlen < 0) + xu = 0 + else + xu = -xvlen + default: # GT_LEFT, GT_NORMAL + # If left justify and drawing to the left, full offset right req'd. + if (xvlen < 0) + xu = -xvlen + else + xu = 0 + } + + switch (TX_VJUSTIFY(tx)) { + case GT_CENTER: + yu = - (yvlen / 2.0) + case GT_TOP: + # If top justify and drawing downward, no offset req'd. + if (yvlen < 0) + yu = 0 + else + yu = -yvlen + default: # GT_BOTTOM, GT_NORMAL + # If bottom justify and drawing downward, full offset up req'd. + if (yvlen < 0) + yu = -yvlen + else + yu = 0 + } + + # ------- XV, YV --------- + # Compute the offset from the center of a single character required + # to justify that character, given a particular character up vector. + # (This could be combined with the above case but is clearer if + # treated separately.) + + p = -DEGTORAD(orien) + cosv = cos(p) + sinv = sin(p) + + # Compute the rotated character in size X and Y. + xsize = abs ( cw * cosv + ch * sinv) + ysize = abs (-cw * sinv + ch * cosv) + + switch (TX_HJUSTIFY(tx)) { + case GT_CENTER: + xv = 0 + case GT_RIGHT: + xv = - (xsize / 2.0) + default: # GT_LEFT, GT_NORMAL + xv = xsize / 2 + } + + switch (TX_VJUSTIFY(tx)) { + case GT_CENTER: + yv = 0 + case GT_TOP: + yv = - (ysize / 2.0) + default: # GT_BOTTOM, GT_NORMAL + yv = ysize / 2 + } + + # ------- X0, Y0 --------- + # The center coordinates of the first character to be drawn are given + # by the reference position plus the string justification vector plus + # the character justification vector. + + x0 = xc + xu + xv + y0 = yc + yu + yv + + # The character drawing primitive requires the coordinates of the + # lower left corner of the character (irrespective of orientation). + # Compute the vector from the center of a character to the lower left + # corner of a character, rotate to the given orientation, and correct + # the starting coordinates by addition of this vector. + + p = - (cw / 2.0) + q = - (ch / 2.0) + + x0 = x0 + ( p * cosv + q * sinv) + y0 = y0 + (-p * sinv + q * cosv) + + # ------- POLYTEXT --------- + # Set the polytext flag. Polytext output is possible only if chars + # are to be drawn to the right with no extra spacing between chars. + + if (abs(dy) == 0 && dx == cw) + polytext = YES + else + polytext = NO +end diff --git a/pkg/images/tv/iis/ids/idstxset.x b/pkg/images/tv/iis/ids/idstxset.x new file mode 100644 index 00000000..3c9529da --- /dev/null +++ b/pkg/images/tv/iis/ids/idstxset.x @@ -0,0 +1,30 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <gset.h> +include <gki.h> +include "../lib/ids.h" + +# IDS_TXSET -- Set the text drawing attributes. + +procedure ids_txset (gki) + +short gki[ARB] # attribute structure + +pointer tx + +include "../lib/ids.com" + +begin + tx = IDS_TXAP(i_kt) + TX_UP(tx) = gki[GKI_TXSET_UP] + TX_PATH(tx) = gki[GKI_TXSET_P ] + TX_HJUSTIFY(tx) = gki[GKI_TXSET_HJ] + TX_VJUSTIFY(tx) = gki[GKI_TXSET_VJ] + TX_FONT(tx) = gki[GKI_TXSET_F ] + TX_QUALITY(tx) = gki[GKI_TXSET_Q ] + TX_COLOR(tx) = gki[GKI_TXSET_CI] + + TX_SPACING(tx) = GKI_UNPACKREAL (gki[GKI_TXSET_SP]) + TX_SIZE(tx) = gki[GKI_TXSET_SZ] + +end diff --git a/pkg/images/tv/iis/ids/idsvector.x b/pkg/images/tv/iis/ids/idsvector.x new file mode 100644 index 00000000..6d1ec502 --- /dev/null +++ b/pkg/images/tv/iis/ids/idsvector.x @@ -0,0 +1,122 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <gki.h> +include <fset.h> +include "../lib/ids.h" + +define MAXC 10000 # just a largish int here + +# IDS_VECTOR -- Plot a line in the current plane; the starting coordinates +# are in ids.com: i_pt_x, i_pt_y. The end points are the arguments +# to vector. +# the code is Bresenham's algorithm, as taken from the line drawing +# routine in Forth-11 image display code. + +procedure ids_vector (ax,ay) + +short ax,ay # vector end coordinates, GKI + +short x,y +short xe ,ye # end coordinates, device +short dx,dy,dd +short xi,yi, xid,yid # increments +short total, e # total change and error +int bufsize # file i/o buffersize +int fstati() +int count, cmax + +include "../lib/ids.com" + +begin + x = ax + y = ay + + bufsize = fstati(i_out, F_BUFSIZE) + + # convert x,y to device coords. + xe = real(x) * i_xres /(GKI_MAXNDC+1) + ye = real(y) * i_yres /(GKI_MAXNDC+1) + + # determine delta x and y, and x/y increments + + dx = xe - i_pt_x + dy = ye - i_pt_y + + # set movement increments, take absolute value of dx, dy + if ( dy >= 0 ) + yi = 1 + else { + yi = -1 + dy = -dy + } + if ( dx >= 0 ) + xi = 1 + else { + xi = -1 + dx = -dx + } + + # set diagonal movement increments + xid = xi + yid = yi + + # if, for instance, pos. slope less than 45 degrees, most movement + # is in x, so then set (the ususal) y increment to zero + if ( dy >= dx ) + xi = 0 + else + yi = 0 + + # Set up for buffer of one, and let code find best buffering + cmax = 0 + call fseti(i_out, F_BUFSIZE, 1) + count = 0 + + # Plot the first point + call ids_rpoint (0, 0) + + # Is there anything to do? determine total increments to plot; if + # zero, quit + total = dx + dy + if ( total == 0 ) { + call fseti (i_out, F_BUFSIZE, bufsize) + return + } + + # set error to zero, determine difference in x,y change. + e = 0 + dd = dy - dx + if ( dd >= 0 ) { + dd = -dd + dy = dx + } + + # plot the line + repeat { + dx = dd + e + if ( (dy + e + dx) >= 0 ) { + # diagonal plot, accounts for two units of increment + if ( count > cmax ) { + # leaving current (x) line, so determine how many points + # have plotted on line and use this (maximum) as line + # buffering size + call fseti(i_out, F_BUFSIZE, count) + cmax = count + count = 0 + } + call ids_rpoint ( xid, yid ) + total = total - 2 + e = dx + } else { + # move in x (or y) only; for the small positive slope line, + # real line will move up and finally over line being plotted, + # hence e increases. + call ids_rpoint ( xi, yi ) + total = total - 1 + e = e + dy + count = count + 1 + } + } until ( total <= 0 ) + # restore original buffer size + call fseti(i_out, F_BUFSIZE, bufsize) +end diff --git a/pkg/images/tv/iis/ids/mkpkg b/pkg/images/tv/iis/ids/mkpkg new file mode 100644 index 00000000..79778100 --- /dev/null +++ b/pkg/images/tv/iis/ids/mkpkg @@ -0,0 +1,43 @@ +# Make the CV package library. + +$checkout libpkg.a ../ +$update libpkg.a +$checkin libpkg.a ../ +$exit + +libpkg.a: + idscancel.x ../lib/ids.com ../lib/ids.h <fset.h> + idschars.x ../lib/ids.com ../lib/ids.h + idsclear.x ../lib/ids.com ../lib/ids.h + idsclose.x ../lib/ids.com ../lib/ids.h + idsclosews.x ../lib/ids.h ../lib/ids.com + idscround.x ../lib/ids.h <gki.h> + idsdrawch.x font.com font.h <gki.h> <gset.h> <math.h> + idsescape.x ../lib/ids.com ../lib/ids.h <gki.h> + idsfa.x ../lib/ids.com ../lib/ids.h + idsfaset.x ../lib/ids.com ../lib/ids.h <gki.h> + idsflush.x ../lib/ids.com ../lib/ids.h + idsfont.x ../lib/ids.com ../lib/ids.h <gki.h> <gset.h> + idsgcell.x <mach.h> ../lib/ids.com ../lib/ids.h <gki.h> <gset.h> + idsgcur.x ../lib/ids.com ../lib/ids.h + idsinit.x ../lib/ids.com ../lib/ids.h <ctype.h> <gki.h> <mach.h> + idsline.x ../lib/ids.com ../lib/ids.h <gset.h> + idslutfill.x <gki.h> + idsopen.x ../lib/ids.com ../lib/ids.h <gki.h> + idsopenws.x ../lib/ids.com ../lib/ids.h <error.h> <gki.h>\ + <fset.h> <mach.h> + idspcell.x ../lib/ids.com ../lib/ids.h <gki.h> <gset.h> + idspl.x ../lib/ids.com ../lib/ids.h <gki.h> + idsplset.x ../lib/ids.com ../lib/ids.h <gki.h> + idspm.x ../lib/ids.com ../lib/ids.h <gki.h> + idspmset.x ../lib/ids.com ../lib/ids.h <gki.h> + idspoint.x ../lib/ids.com ../lib/ids.h <fset.h> <gki.h> + idsreset.x ../lib/ids.com ../lib/ids.h <gset.h> <gki.h> + idsrestore.x ../lib/ids.com ../lib/ids.h + idssave.x ../lib/ids.com ../lib/ids.h + idsscur.x + idsstream.x ../lib/ids.com ../lib/ids.h + idstx.x ../lib/ids.com ../lib/ids.h <gki.h> <gset.h> <math.h> + idstxset.x ../lib/ids.com ../lib/ids.h <gki.h> <gset.h> + idsvector.x ../lib/ids.com ../lib/ids.h <fset.h> <gki.h> + ; diff --git a/pkg/images/tv/iis/ids/testcode/README b/pkg/images/tv/iis/ids/testcode/README new file mode 100644 index 00000000..31198b43 --- /dev/null +++ b/pkg/images/tv/iis/ids/testcode/README @@ -0,0 +1,2 @@ +This is junk code which I think should be thrown away. I will leave it here +for the time just in case. (LED 22/4/91) diff --git a/pkg/images/tv/iis/ids/testcode/box.x b/pkg/images/tv/iis/ids/testcode/box.x new file mode 100644 index 00000000..e3c1d22b --- /dev/null +++ b/pkg/images/tv/iis/ids/testcode/box.x @@ -0,0 +1,83 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "imd.h" +include <gki.h> + +define DIM 512 +define MCXSCALE 64 +define MCYSCALE 64 + +# create a box test image + +procedure t_im() + +pointer gp +char output[SZ_FNAME], output_file[SZ_FNAME], device[SZ_FNAME] +int fd + +pointer gopen() +bool streq() +int open() + +short i,data[DIM+1] +short set_image[6] +int key +real x[30],y[30] +real lb,ub,mid +int mod() + +begin + call clgstr("output", output, SZ_FNAME) + if (!streq (output, "") ) { + call strcpy (output, output_file, SZ_FNAME) + fd = open (output_file, NEW_FILE, BINARY_FILE) + } else + fd = open ("dev$stdimage", NEW_FILE, BINARY_FILE) + + call clgstr("device", device, SZ_FNAME) + gp = gopen ( device, NEW_FILE, fd) + + # now set up boxes + set_image[1] = 1 + set_image[2] = IMD_EOD + set_image[3] = IMD_BLUE + set_image[4] = IMD_EOD + call gescape ( gp, IMD_SET_GP, set_image, 4) + lb = 0.0 + ub = 1.0 + mid = (lb + ub)/2. + for ( i = 1; i <= 5 ; i = i + 1 ) { + if ( mod(i-1,2) == 0 ) { + x[1] = lb + y[1] = mid + x[2] = mid + y[2] = ub + x[3] = ub + y[3] = mid + x[4] = mid + y[4] = lb + x[5] = lb + y[5] = mid + } else { + x[1] = (mid-lb)/2 + lb + y[1] = x[1] + x[2] = x[1] + # x[2] = x[1] - .05 + y[2] = y[1] + mid - lb + x[3] = y[2] + y[3] = y[2] + # y[3] = y[2] - .05 + x[4] = y[2] + y[4] = x[1] + x[5] = x[1] + y[5] = y[1] + lb = x[1] + ub = y[2] + } + call gpline ( gp, x, y, 5) + } + + # all done + call gclose ( gp ) + call close ( fd ) +end diff --git a/pkg/images/tv/iis/ids/testcode/boxin.x b/pkg/images/tv/iis/ids/testcode/boxin.x new file mode 100644 index 00000000..e854935f --- /dev/null +++ b/pkg/images/tv/iis/ids/testcode/boxin.x @@ -0,0 +1,98 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <error.h> +include <fio.h> +include <fset.h> +include "ids.h" +include <gki.h> + +define DIM 512 +define MCXSCALE 64 +define MCYSCALE 64 + +# create a box test image + +procedure t_im() + +pointer gp +char device[SZ_FNAME] + +pointer gopen() +int dd[LEN_GKIDD] + +short i,data[DIM+1] +short set_image[6] +int key, j +real x[30],y[30] +real lb,ub,mid +int mod() + +begin + call clgstr("device", device, SZ_FNAME) + call ids_open (device, dd) + call gki_inline_kernel (STDIMAGE, dd) + gp = gopen ( device, NEW_FILE, STDIMAGE) + + call fseti (STDIMAGE, F_TYPE, SPOOL_FILE) + call fseti (STDIMAGE, F_CANCEL, OK) + + # enable the blue plane + set_image[1] = IDS_ON + set_image[2] = IDS_EOD # all graphics frames + set_image[3] = IDS_BLUE # color + set_image[4] = IDS_EOD + set_image[5] = IDS_EOD # all quadrants + call gescape ( gp, IDS_DISPLAY_G, set_image, 5) + + # set which plane to write into + set_image[1] = 1 + set_image[2] = IDS_EOD # first graphics frame + set_image[3] = IDS_BLUE # color + set_image[4] = IDS_EOD + call gescape ( gp, IDS_SET_GP, set_image, 4) + + # now set up boxes + lb = 0.0 + ub = 1.0 + mid = (lb + ub)/2. + for ( i = 1; i <= 5 ; i = i + 1 ) { + if ( mod(i-1,2) == 0 ) { + x[1] = lb + y[1] = mid + x[2] = mid + y[2] = ub + x[3] = ub + y[3] = mid + x[4] = mid + y[4] = lb + x[5] = lb + y[5] = mid + } else { + x[1] = (mid-lb)/2 + lb + y[1] = x[1] + x[2] = x[1] + y[2] = y[1] + mid - lb + x[3] = y[2] + y[3] = y[2] + x[4] = y[2] + y[4] = x[1] + x[5] = x[1] + y[5] = y[1] + lb = x[1] + ub = y[2] + } + do j = 1,5 { + x[j] = x[j] * 32768. / 32767. + if (x[j] > 1.0) + x[j] = 1.0 + y[j] = y[j] * 32768. / 32767. + if (y[j] > 1.0) + y[j] = 1.0 + } + call gpline ( gp, x, y, 5) + } + + # all done + call gclose ( gp ) + call ids_close +end diff --git a/pkg/images/tv/iis/ids/testcode/crin.x b/pkg/images/tv/iis/ids/testcode/crin.x new file mode 100644 index 00000000..c9d27279 --- /dev/null +++ b/pkg/images/tv/iis/ids/testcode/crin.x @@ -0,0 +1,130 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <error.h> +include <fio.h> +include <fset.h> +include "ids.h" +include <gki.h> +include <gset.h> + +define DIM 512 +define MCXSCALE 64 +define MCYSCALE 64 + +# zoom + +procedure t_im() + +pointer gp +char device[SZ_FNAME] + +pointer gopen() +int dd[LEN_GKIDD] + +short i, data[DIM+1] +int key, but, fnum +real x, y +real xjunk, yjunk + +begin + call clgstr("device", device, SZ_FNAME) + call ids_open (device, dd) + call gki_inline_kernel (STDIMAGE, dd) + gp = gopen ( device, NEW_FILE, STDIMAGE) + + call fseti (STDIMAGE, F_TYPE, SPOOL_FILE) + call fseti (STDIMAGE, F_CANCEL, OK) + call ids_grstream (STDIMAGE) + + # read first to clear box + call gseti(gp, G_CURSOR, IDS_BUT_RD) + call ggcur(gp, xjunk, yjunk, key) + + i = 1 + repeat { + call eprintf("set zoom and zoom center\n") + call gseti (gp, G_CURSOR, IDS_BUT_WT) + call ggcur(gp, x, y, but) + call gseti (gp, G_CURSOR, 1) + call ggcur(gp, x, y, key) + call zm(gp, but, x, y) + call eprintf("set frame, 4 to exit\n") + call gseti (gp, G_CURSOR, IDS_BUT_WT) + call ggcur(gp, xjunk, yjunk, fnum) + if ( fnum == 4) + break + call iset(gp, fnum) + repeat { + call gseti (gp, G_CURSOR, IDS_BUT_WT) + call ggcur(gp, xjunk, yjunk, but) + call gseti (gp, G_CURSOR, fnum) + call rpc(gp, x, y, key) + call ggcell (gp, data, 1, 1, x, y, x, y) + call eprintf("frame %d, datum: %d\n") + call pargi (fnum) + call pargs (data[1]) + } until ( but == 4) + } until ( i == 0 ) + + + # all done + call gclose ( gp ) + call ids_close +end + +# rpcursor --- read and print cursor + +procedure rpc(gp, sx, sy, key) + +pointer gp +real sx,sy +int key + +begin + call ggcur (gp, sx, sy, key) + call eprintf("cursor: (%f,%f) (%d,%d) key %d\n") + call pargr (sx) + call pargr (sy) + call pargi ( int(sx*32767)/64) + call pargi ( int(sy*32767)/64) + call pargi (key) +end + +# zoom + +procedure zm(gp, pow, x, y) + +int pow +pointer gp +real x, y + +short data[9] + +begin + data[1] = IDS_ZOOM + data[2] = IDS_WRITE + data[3] = 3 + data[4] = IDS_EOD + data[5] = IDS_EOD + data[6] = 0 + data[7] = 2**(pow-1) + data[8] = x * GKI_MAXNDC + data[9] = y * GKI_MAXNDC + call gescape ( gp, IDS_CONTROL, data[1], 9) +end + +# set image plane for operation + +procedure iset (gp, frame) + +int frame +pointer gp + +short data[10] + +begin + data[1] = frame + data[2] = IDS_EOD + data[3] = IDS_EOD # all bitplanes + call gescape (gp, IDS_SET_IP, data, 3) +end diff --git a/pkg/images/tv/iis/ids/testcode/grey.x b/pkg/images/tv/iis/ids/testcode/grey.x new file mode 100644 index 00000000..a7e16b83 --- /dev/null +++ b/pkg/images/tv/iis/ids/testcode/grey.x @@ -0,0 +1,90 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "imd.h" + +define DIM 512 +define MCXSCALE 64 +define MCYSCALE 64 + +# create a grey scale test image, using frames 1 and 2, and +# position the cursor in the upper right quadrant. + +procedure t_im() + +pointer gp +char output[SZ_FNAME], output_file[SZ_FNAME], device[SZ_FNAME] +int fd + +pointer gopen() +bool streq() +int open() + +short i,data[DIM+1] +short display[6] +short set_image[3] +real y, sx, sy +int key + +begin + call clgstr("output", output, SZ_FNAME) + if (!streq (output, "") ) { + call strcpy (output, output_file, SZ_FNAME) + fd = open (output_file, NEW_FILE, BINARY_FILE) + } else + fd = open ("dev$stdimage", NEW_FILE, BINARY_FILE) + + call clgstr("device", device, SZ_FNAME) + gp = gopen ( device, NEW_FILE, fd) + + data[1] = IMD_R_HARD + call gescape ( gp, IMD_RESET, data, 1) + # display all frames off + display[1] = IMD_OFF + display[2] = IMD_EOD # all frames + display[3] = IMD_EOD # all colors + display[4] = IMD_EOD # all quads + call gescape ( gp, IMD_DISPLAY_I, display, 6) + # display frames 1, 2 on -- 1 red, 2 green + display[1] = IMD_ON + display[2] = 1 + display[3] = IMD_EOD + display[4] = IMD_RED + display[5] = IMD_EOD + display[6] = IMD_EOD # all quads + call gescape ( gp, IMD_DISPLAY_I, display, 6) + display[1] = IMD_ON + display[2] = 2 + display[3] = IMD_EOD + display[4] = IMD_GREEN + display[5] = IMD_EOD + display[6] = IMD_EOD # all quads + call gescape ( gp, IMD_DISPLAY_I, display, 6) + + # now set up grey scale changing upward in frame 1 + set_image[1] = 1 + set_image[2] = IMD_EOD + set_image[3] = IMD_EOD # all planes + call gescape ( gp, IMD_SET_IP, set_image, 3) + for ( i = 1; i <= DIM ; i = i + 1 ) { + call amovks ( i-1, data, DIM) + y = real(i-1)/(DIM-1) + call gpcell ( gp, data, DIM, 1, 0., y, 1., y) + } + + # grey scale changing horizontally in frame 2 + set_image[1] = 2 + call gescape ( gp, IMD_SET_IP, set_image, 3) + do i = 1, DIM + data[i] = i + call gpcell ( gp, data, DIM, 1, 0., 0., 1., 1.) + + # set the cursor + call gscur ( gp, 0.0, 1.0) + + # read cursor + # call ggcur( gp, sx, sy, key) + + # all done + call gclose ( gp ) + call close ( fd ) +end diff --git a/pkg/images/tv/iis/ids/testcode/grin.x b/pkg/images/tv/iis/ids/testcode/grin.x new file mode 100644 index 00000000..b76e58b2 --- /dev/null +++ b/pkg/images/tv/iis/ids/testcode/grin.x @@ -0,0 +1,98 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <error.h> +include <fio.h> +include <fset.h> +include <gki.h> +include "ids.h" + +define DIM 512 +define MCXSCALE 64 +define MCYSCALE 64 + +# create a grey scale test image, using frames 1 and 2, and +# position the cursor in the upper right quadrant. + +procedure t_im() + +pointer gp +char device[SZ_FNAME] + +pointer gopen() +int open() +int dd[LEN_GKIDD] + +short i,data[DIM+1] +short display[6] +short set_image[3] +real y, sx, sy +int key + +begin + call clgstr("device", device, SZ_FNAME) + call ids_open (device, dd) + call gki_inline_kernel (STDIMAGE, dd) + gp = gopen ( device, NEW_FILE, STDIMAGE) + + call fseti (STDIMAGE, F_TYPE, SPOOL_FILE) + call fseti (STDIMAGE, F_CANCEL, OK) + call ids_grstream(STDIMAGE) + + data[1] = IDS_R_HARD + call gescape ( gp, IDS_RESET, data, 1) + # display all frames off + display[1] = IDS_OFF + display[2] = IDS_EOD # all frames + display[3] = IDS_EOD # all colors + display[4] = IDS_EOD # all quads + call gescape ( gp, IDS_DISPLAY_I, display, 6) + # display frames 1, 2 on -- 1 red, 2 green + display[1] = IDS_ON + display[2] = 1 + display[3] = IDS_EOD + display[4] = IDS_RED + display[5] = IDS_EOD + display[6] = IDS_EOD # all quads + call gescape ( gp, IDS_DISPLAY_I, display, 6) + display[1] = IDS_ON + display[2] = 2 + display[3] = IDS_EOD + display[4] = IDS_GREEN + display[5] = IDS_EOD + display[6] = IDS_EOD # all quads + call gescape ( gp, IDS_DISPLAY_I, display, 6) + + # now set up grey scale changing upward in frame 1 + set_image[1] = 1 + set_image[2] = IDS_EOD + set_image[3] = IDS_EOD # all planes + call gescape ( gp, IDS_SET_IP, set_image, 3) + for ( i = 1; i <= DIM ; i = i + 1 ) { + call amovks ( i-1, data, DIM) + y = real(i-1)/(DIM-1) + call gpcell ( gp, data, DIM, 1, 0., y, 1., y) + } + + # grey scale changing horizontally in frame 2 + set_image[1] = 2 + call gescape ( gp, IDS_SET_IP, set_image, 3) + do i = 1, DIM + data[i] = i-1 + call gpcell ( gp, data, DIM, 1, 0., 0., 1., 1.) + + # set the cursor + call gscur ( gp, 0.0, 1.0) + + # read cursor + call ggcur (gp, sx, sy, key) + call eprintf("cursor read as : (%f,%f) (%d,%d), key %d\n") + call pargr (sx) + call pargr (sy) + call pargi ( int(sx*32767)/64) + call pargi ( int(sy*32767)/64) + call pargi (key) + + # all done + call gclose (gp) + call ids_close +end diff --git a/pkg/images/tv/iis/ids/testcode/scr.x b/pkg/images/tv/iis/ids/testcode/scr.x new file mode 100644 index 00000000..ec4821cf --- /dev/null +++ b/pkg/images/tv/iis/ids/testcode/scr.x @@ -0,0 +1,130 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "imd.h" +include <gset.h> +include <gki.h> + +define DIM 512 +define MCXSCALE 64 +define MCYSCALE 64 + +# scroll + +procedure t_im() + +pointer gp +char output[SZ_FNAME], output_file[SZ_FNAME], device[SZ_FNAME] +int fd + +pointer gopen() +bool streq() +int open() +common /local/gp + +begin + call clgstr("output", output, SZ_FNAME) + if (!streq (output, "") ) { + call strcpy (output, output_file, SZ_FNAME) + fd = open (output_file, NEW_FILE, BINARY_FILE) + } else + fd = open ("dev$stdimage", NEW_FILE, BINARY_FILE) + + call clgstr("device", device, SZ_FNAME) + gp = gopen ( device, NEW_FILE, fd) + + call cl_button + call scroll(0,0) + call cursor(128,128) + call wt_button + call scroll(128,195) + call cursor(128,128) + call wt_button + call zm(4,128,128) + call wt_button + call cursor(128,128) + call wt_button + call zm(1,205,205) + + # all done + call gclose ( gp ) + call close ( fd ) +end + +procedure scroll(x,y) + +int x,y + +pointer gp +common /local/gp +short data[8] + +begin + data[1] = IMD_SCROLL + data[2] = IMD_WRITE + data[3] = 2 + data[4] = IMD_EOD + data[5] = IMD_EOD + data[6] = 0 + data[7] = (x-1) * MCXSCALE + data[8] = (y-1) * MCYSCALE + call gescape(gp, IMD_CONTROL, data, 8) +end + +procedure cursor(x,y) + +int x,y +pointer gp +real xr, yr +common /local/gp + +begin + xr = real((x-1)*MCXSCALE)/GKI_MAXNDC + yr = real((y-1)*MCXSCALE)/GKI_MAXNDC + call gseti(gp, G_CURSOR, 1) + call gscur(gp, xr, yr) +end + +procedure wt_button + +real x,y +int key +pointer gp +common /local/gp +begin + call gseti(gp, G_CURSOR, IMD_BUT_WT) + call ggcur(gp, x, y, key) +end + +procedure cl_button + +real x,y +int key +pointer gp +common /local/gp + +begin + call gseti(gp, G_CURSOR, IMD_BUT_RD) + call ggcur(gp, x, y, key) +end + +procedure zm(power, x,y) + +int power +int x,y + +short data[9] +pointer gp +common /local/gp + +begin + data[1] = IMD_ZOOM + data[2] = IMD_WRITE + data[3] = 3 + data[4] = IMD_EOD + data[5] = IMD_EOD + data[6] = 0 + data[7] = power + data[8] = (x-1) * MCXSCALE + data[9] = (y-1) * MCYSCALE + call gescape(gp, IMD_CONTROL, data, 9) +end diff --git a/pkg/images/tv/iis/ids/testcode/scrin.x b/pkg/images/tv/iis/ids/testcode/scrin.x new file mode 100644 index 00000000..7a704fe4 --- /dev/null +++ b/pkg/images/tv/iis/ids/testcode/scrin.x @@ -0,0 +1,130 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <error.h> +include <fio.h> +include <fset.h> +include "ids.h" +include <gset.h> +include <gki.h> + +define DIM 512 +define MCXSCALE 64 +define MCYSCALE 64 + +# scroll + +procedure t_im() + +pointer gp +char device[SZ_FNAME] + +pointer gopen() +int dd[LEN_GKIDD] +common /local/gp + +begin + call clgstr("device", device, SZ_FNAME) + call ids_open (device, dd) + call gki_inline_kernel (STDIMAGE, dd) + gp = gopen ( device, NEW_FILE, STDIMAGE) + + call fseti (STDIMAGE, F_TYPE, SPOOL_FILE) + call fseti (STDIMAGE, F_CANCEL, OK) + call ids_grstream (STDIMAGE) + + call cl_button + call scroll(1,1) + call cursor(129,129) + call wt_button + call scroll(129,195) + call cursor(129,129) + call wt_button + call zm(4,129,129) + call wt_button + call cursor(129,129) + call wt_button + call zm(1,205,205) + + # all done + call gclose ( gp ) + call ids_close +end + +procedure scroll(x,y) + +int x,y + +pointer gp +common /local/gp +short data[8] + +begin + data[1] = IDS_SCROLL + data[2] = IDS_WRITE + data[3] = 2 + data[4] = IDS_EOD + data[5] = IDS_EOD + data[6] = 0 + data[7] = (x-1) * MCXSCALE + data[8] = (y-1) * MCYSCALE + call gescape(gp, IDS_CONTROL, data, 8) +end + +procedure cursor(x,y) + +int x,y +pointer gp +real xr, yr +common /local/gp + +begin + xr = real((x-1)*MCXSCALE)/GKI_MAXNDC + yr = real((y-1)*MCXSCALE)/GKI_MAXNDC + call gseti(gp, G_CURSOR, 1) + call gscur(gp, xr, yr) +end + +procedure wt_button + +real x,y +int key +pointer gp +common /local/gp +begin + call gseti(gp, G_CURSOR, IDS_BUT_WT) + call ggcur(gp, x, y, key) +end + +procedure cl_button + +real x,y +int key +pointer gp +common /local/gp + +begin + call gseti(gp, G_CURSOR, IDS_BUT_RD) + call ggcur(gp, x, y, key) +end + +procedure zm(power, x,y) + +int power +int x,y + +short data[9] +pointer gp +common /local/gp + +begin + data[1] = IDS_ZOOM + data[2] = IDS_WRITE + data[3] = 3 + data[4] = IDS_EOD + data[5] = IDS_EOD + data[6] = 0 + data[7] = power + data[8] = (x-1) * MCXSCALE + data[9] = (y-1) * MCYSCALE + call gescape(gp, IDS_CONTROL, data, 9) +end diff --git a/pkg/images/tv/iis/ids/testcode/sn.x b/pkg/images/tv/iis/ids/testcode/sn.x new file mode 100644 index 00000000..ebce47c0 --- /dev/null +++ b/pkg/images/tv/iis/ids/testcode/sn.x @@ -0,0 +1,192 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <error.h> +include <fio.h> +include <fset.h> +include "ids.h" +include <gki.h> +include <gset.h> +include <imhdr.h> + +define DIM 512 +define MCXSCALE 64 +define MCYSCALE 64 + +# snap + +procedure t_im() + +pointer gp +char device[SZ_FNAME] +char cjunk[SZ_FNAME] + +pointer gopen() +int dd[LEN_GKIDD] + +int key, fnum, zfac +int ps, pe +real x, y +real xjunk, yjunk +int clgeti +bool image, clgetb + +begin + call clgstr("device", device, SZ_FNAME) + call ids_open (device, dd) + call gki_inline_kernel (STDIMAGE, dd) + gp = gopen ( device, NEW_FILE, STDIMAGE) + + call fseti (STDIMAGE, F_TYPE, SPOOL_FILE) + call fseti (STDIMAGE, F_CANCEL, OK) + call ids_grstream (STDIMAGE) + + # read first to clear box + call gseti(gp, G_CURSOR, IDS_BUT_RD) + call ggcur(gp, xjunk, yjunk, key) + + repeat { + if (clgetb ("done?")) + break + + zfac = clgeti ("zoom factor") + + call clgstr ("Set zoom center, press <cr>", cjunk, SZ_FNAME) + call gseti (gp, G_CURSOR, 1) + call ggcur(gp, x, y, key) + call zm(gp, zfac, x, y) + + image = clgetb("Do you want a picture?") + if (image) + call snapi (gp) + else { + repeat { + ps = clgeti ("starting line") + if ( ps == -1) + break + pe = clgeti ("ending line") + call snap (gp, ps, pe) + } + } + } + + + # all done + call gclose ( gp ) + call ids_close +end + +# zoom + +procedure zm(gp, pow, x, y) + +int pow +pointer gp +real x, y + +short data[9] + +begin + data[1] = IDS_ZOOM + data[2] = IDS_WRITE + data[3] = 3 + data[4] = IDS_EOD + data[5] = IDS_EOD + data[6] = 0 + data[7] = 2**(pow-1) + data[8] = x * GKI_MAXNDC + data[9] = y * GKI_MAXNDC + call gescape ( gp, IDS_CONTROL, data[1], 9) +end + +procedure snap (gp, ps, pe) + +pointer gp +int ps, pe + +real y +short data[7] +pointer sp +pointer sndata +int i,j + +begin + call smark (sp) + data[1] = IDS_SNAP + data[2] = IDS_WRITE + data[3] = 1 + data[4] = IDS_EOD + data[5] = IDS_EOD + data[6] = 0 + data[7] = IDS_SNAP_RGB + call gescape (gp, IDS_CONTROL, data, 7) + + if (pe < ps) { + call eprintf("Can't handle ending position < start \n") + return + } + + call salloc ( sndata, DIM, TY_SHORT) + call eprintf ("snapping from %d through %d\n") + call pargi (ps) + call pargi (pe) + call eprintf ("data values 0-5 255 256 511\n") + do i = ps, pe { + y = real(i)*MCYSCALE / GKI_MAXNDC. + call ggcell (gp, Mems[sndata], DIM, 1, 0.0, y, 1.0, y) + call eprintf ("r%3d data:") + call pargi (i) + call eprintf (" %5d %5d %5d %5d %5d %5d %5d %5d %5d\n") + do j = 0, 5 + call pargs (Mems[sndata+j]) + call pargs (Mems[sndata+255]) + call pargs (Mems[sndata+256]) + call pargs (Mems[sndata+511]) + } + + data[1] = IDS_R_SNAPDONE + call gescape (gp, IDS_RESET, data, 1) + + call sfree (sp) +end + +procedure snapi (gp) + +pointer gp + +real y +short data[7] +pointer im, immap(), impl2s() +char fname[SZ_FNAME] +int i + +begin + call clgstr ("file", fname, SZ_FNAME) + im = immap(fname, NEW_FILE, 0) + IM_PIXTYPE(im) = TY_SHORT + IM_LEN(im,1) = DIM + IM_LEN(im,2) = DIM + + data[1] = IDS_SNAP + data[2] = IDS_WRITE + data[3] = 1 + data[4] = IDS_EOD + data[5] = IDS_EOD + data[6] = 0 + data[7] = IDS_SNAP_RGB + call gescape (gp, IDS_CONTROL, data, 7) + + do i = 0, 511 { + if ( mod(i,52) == 0) { + call eprintf ("%d ") + call pargi (100*i/DIM) + call flush (STDERR) + } + y = real(i)*MCYSCALE / GKI_MAXNDC. + call ggcell (gp, Mems[impl2s(im,i+1)], 512, 1, 0.0, y, 1.0, y) + } + call eprintf ("\n") + + call imunmap(im) + data[1] = IDS_R_SNAPDONE + call gescape (gp, IDS_RESET, data, 1) +end diff --git a/pkg/images/tv/iis/ids/testcode/t_giis.x b/pkg/images/tv/iis/ids/testcode/t_giis.x new file mode 100644 index 00000000..601bc17b --- /dev/null +++ b/pkg/images/tv/iis/ids/testcode/t_giis.x @@ -0,0 +1,67 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <error.h> +include <gki.h> + +# GIIS -- Graphics kernel for image output to the IIS. +# The whole package is copied as much as possible from the stdgraph package. + +procedure t_giis() + +int fd, list +pointer gki, sp, fname, devname +int dev[LEN_GKIDD], deb[LEN_GKIDD] +int debug, verbose, gkiunits +bool clgetb() +int clpopni(), clgfil(), open(), btoi() +int gki_fetch_next_instruction() + +begin + call smark (sp) + call salloc (fname, SZ_FNAME, TY_CHAR) + call salloc (devname, SZ_FNAME, TY_CHAR) + + # Open list of metafiles to be decoded. + list = clpopni ("input") + + # Get parameters. + call clgstr ("device", Memc[devname], SZ_FNAME) + if (clgetb ("generic")) { + debug = NO + verbose = NO + gkiunits = NO + } else { + debug = btoi (clgetb ("debug")) + verbose = btoi (clgetb ("verbose")) + gkiunits = btoi (clgetb ("gkiunits")) + } + + # Open the graphics kernel. + call ids_open (Memc[devname], dev) + call gkp_install (deb, STDERR, verbose, gkiunits) + + # Process a list of metacode files, writing the decoded metacode + # instructions on the standard output. + + while (clgfil (list, Memc[fname], SZ_FNAME) != EOF) { + # Open input file. + iferr (fd = open (Memc[fname], READ_ONLY, BINARY_FILE)) { + call erract (EA_WARN) + next + } + + # Process the metacode instruction stream. + while (gki_fetch_next_instruction (fd, gki) != EOF) { + if (debug == YES) + call gki_execute (Mems[gki], deb) + call gki_execute (Mems[gki], dev) + } + + call close (fd) + } + + call gkp_close() + call ids_close() + call clpcls (list) + call sfree (sp) +end diff --git a/pkg/images/tv/iis/ids/testcode/zm.x b/pkg/images/tv/iis/ids/testcode/zm.x new file mode 100644 index 00000000..dff01cbe --- /dev/null +++ b/pkg/images/tv/iis/ids/testcode/zm.x @@ -0,0 +1,64 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "imd.h" +include <gki.h> +include <gset.h> + +define DIM 512 +define MCXSCALE 64 +define MCYSCALE 64 + +# zoom + +procedure t_im() + +pointer gp +char output[SZ_FNAME], output_file[SZ_FNAME], device[SZ_FNAME] +int fd + +pointer gopen() +bool streq() +int open() + +short i,data[DIM+1] +short set_image[6] +int key +real x[30],y[30] +int xjunk, yjunk + +begin + call clgstr("output", output, SZ_FNAME) + if (!streq (output, "") ) { + call strcpy (output, output_file, SZ_FNAME) + fd = open (output_file, NEW_FILE, BINARY_FILE) + } else + fd = open ("dev$stdimage", NEW_FILE, BINARY_FILE) + + call clgstr("device", device, SZ_FNAME) + gp = gopen ( device, NEW_FILE, fd) + + # now zoom after reading button presses + # read first to clear box + call gseti(gp, G_CURSOR, IMD_BUT_RD) + call ggcur(gp, xjunk, yjunk, key) + + for ( i = 1 ; i < 5 ; i = i + 1) { + call gseti(gp, G_CURSOR, IMD_BUT_WT) + call ggcur(gp, xjunk, yjunk, key) + + data[11] = IMD_ZOOM + data[12] = IMD_WRITE + data[13] = 3 + data[14] = IMD_EOD + data[15] = IMD_EOD + data[16] = 0 + data[17] = 4 + data[18] = (((i-1)* 128)-1) * MCXSCALE + data[19] = (((i-1)* 128)-1) * MCYSCALE + call gescape ( gp, IMD_CONTROL, data[11], 9) + } + + # all done + call gclose ( gp ) + call close ( fd ) +end diff --git a/pkg/images/tv/iis/ids/testcode/zmin.x b/pkg/images/tv/iis/ids/testcode/zmin.x new file mode 100644 index 00000000..676a72f0 --- /dev/null +++ b/pkg/images/tv/iis/ids/testcode/zmin.x @@ -0,0 +1,84 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <error.h> +include <fio.h> +include <fset.h> +include "ids.h" +include <gki.h> +include <gset.h> + +define DIM 512 +define MCXSCALE 64 +define MCYSCALE 64 + +# zoom + +procedure t_im() + +pointer gp +char device[SZ_FNAME] + +pointer gopen() +int dd[LEN_GKIDD] + +short i,data[DIM+1] +short set_image[6] +int key +real x[30],y[30] +real xjunk, yjunk + +begin + call clgstr("device", device, SZ_FNAME) + call ids_open (device, dd) + call gki_inline_kernel (STDIMAGE, dd) + gp = gopen ( device, NEW_FILE, STDIMAGE) + + call fseti (STDIMAGE, F_TYPE, SPOOL_FILE) + call fseti (STDIMAGE, F_CANCEL, OK) + call ids_grstream (STDIMAGE) + + # now zoom after reading button presses + # read first to clear box + call gseti(gp, G_CURSOR, IDS_BUT_RD) + call ggcur(gp, xjunk, yjunk, key) + + for ( i = 1 ; i < 5 ; i = i + 1) { + call gseti (gp, G_CURSOR, IDS_BUT_WT) + call ggcur(gp, xjunk, yjunk, key) + call gseti (gp, G_CURSOR, 1) + call rpc(gp, xjunk, yjunk, key) + + data[11] = IDS_ZOOM + data[12] = IDS_WRITE + data[13] = 3 + data[14] = IDS_EOD + data[15] = IDS_EOD + data[16] = 0 + data[17] = 4 + data[18] = min(((i-1)* 128) * MCXSCALE, GKI_MAXNDC) + data[19] = min(((i-1)* 128) * MCYSCALE, GKI_MAXNDC) + call gescape ( gp, IDS_CONTROL, data[11], 9) + } + + # all done + call gclose ( gp ) + call ids_close +end + +# rpcursor --- read and print cursor + +procedure rpc(gp, sx, sy, key) + +pointer gp +real sx,sy +int key + +begin + call ggcur (gp, sx, sy, key) + call eprintf("cursor: (%f,%f) (%d,%d) key %d\n") + call pargr (sx) + call pargr (sy) + call pargi ( int(sx*32767)/64) + call pargi ( int(sy*32767)/64) + call pargi (key) +end diff --git a/pkg/images/tv/iis/ids/testcode/zztest.x b/pkg/images/tv/iis/ids/testcode/zztest.x new file mode 100644 index 00000000..599b7103 --- /dev/null +++ b/pkg/images/tv/iis/ids/testcode/zztest.x @@ -0,0 +1,81 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <fset.h> +include <gset.h> + +define XS 0.216 +define XE 0.719 +define YS 0.214 +define YE 0.929 + +task test = t_test + +# T_TEST -- Test program for graphics plotting. A labelled grid is output. + +procedure t_test () + +bool redir +pointer sp, gp +char command[SZ_LINE], image[SZ_FNAME], word[SZ_LINE] +char output[SZ_FNAME], output_file[SZ_FNAME], device[SZ_FNAME] +int cmd, input_fd, stat, fd + +pointer gopen() +bool streq() +int fstati(), open(), getline() + +begin + # If the input has been redirected, input is read from the named + # command file. If not, each image name in the input template is + # plotted. + + if (fstati (STDIN, F_REDIR) == YES) { +call eprintf ("Input has been redirected\n") + redir = true + cmd = open (STDIN, READ_ONLY, TEXT_FILE) + } + + # Loop over commands until EOF + repeat { + if (redir) { + if (getline (STDIN, command, SZ_LINE) == EOF) + break + call sscan (command) + call gargwrd (word, SZ_LINE) + if (!streq (word, "plot")) { + # Pixel window has been stored as WCS 2 + call gseti (gp, G_WCS, 2) + call gscan (command) + next + } else + call gargwrd (image) + } + + call clgstr ("output", output, SZ_FNAME) + if (!streq (output, "")) { + call strcpy (output, output_file, SZ_FNAME) + fd = open (output_file, NEW_FILE, BINARY_FILE) + } else + fd = open ("dev$crt", NEW_FILE, BINARY_FILE) + + call clgstr ("device", device, SZ_FNAME) + gp = gopen (device, NEW_FILE, fd) + + call gseti (gp, G_XDRAWGRID, 1) + call gseti (gp, G_YDRAWGRID, 1) + call gseti (gp, G_NMAJOR, 21) + call glabax (gp, "TEST", "NDC_X", "NDC_Y") + call gline (gp, XS, YS, XE, YS) + call gline (gp, XE, YS, XE, YE) + call gline (gp, XE, YE, XS, YE) + call gline (gp, XS, YE, XS, YS) + call gmark (gp, 0.5, 0.5, GM_CROSS, 3.0, 3.0) + call gtext (gp, XS, YS-0.1, "DICOMED crtpict film area") + call gclose (gp) + call close (fd) + } + + call clpcls (input_fd) + call sfree (sp) +end diff --git a/pkg/images/tv/iis/iis.cl b/pkg/images/tv/iis/iis.cl new file mode 100644 index 00000000..becb72c4 --- /dev/null +++ b/pkg/images/tv/iis/iis.cl @@ -0,0 +1,22 @@ +plot + +#{ IIS -- The IIS Image Display Control package. + +package iis + +set iis = "images$tv/iis/" + +task cv, + cvl = "iis$x_iis.e" + +task blink = "iis$blink.cl" +task erase = "iis$erase.cl" +task $frame = "iis$frame.cl" +task lumatch = "iis$lumatch.cl" +task $monochrome = "iis$monochrome.cl" +task pseudocolor = "iis$pseudocolor.cl" +task rgb = "iis$rgb.cl" +task $window = "iis$window.cl" +task zoom = "iis$zoom.cl" + +clbye() diff --git a/pkg/images/tv/iis/iis.hd b/pkg/images/tv/iis/iis.hd new file mode 100644 index 00000000..a0be19f2 --- /dev/null +++ b/pkg/images/tv/iis/iis.hd @@ -0,0 +1,16 @@ +# Help directory for the IIS package + +$doc = "images$tv/iis/doc/" +$iis = "images$tv/iis/" + +blink hlp=doc$blink.hlp, src=iis$blink.cl +cv hlp=doc$cv.hlp src=iis$src/cv.x +cvl hlp=doc$cvl.hlp +erase hlp=doc$erase.hlp, src=iis$erase.cl +frame hlp=doc$frame.hlp, src=iis$frame.cl +lumatch hlp=doc$lumatch.hlp, src=iis$lumatch.cl +monochrome hlp=doc$monochrome.hlp, src=iis$monochrome.cl +pseudocolor hlp=doc$pseudocolor.hlp, src=iis$pseudocolor.cl +rgb hlp=doc$rgb.hlp, src=iis$rgb.cl +window hlp=doc$window.hlp, src=iis$window.cl +zoom hlp=doc$zoom.hlp, src=iis$zoom.cl diff --git a/pkg/images/tv/iis/iis.men b/pkg/images/tv/iis/iis.men new file mode 100644 index 00000000..08123e61 --- /dev/null +++ b/pkg/images/tv/iis/iis.men @@ -0,0 +1,11 @@ + blink - Blink two frames + cv - Control image device, display "snapshot" + cvl - Load image display (newer version of 'display') + erase - Erase an image frame + frame - Select the frame to be displayed + lumatch - Match the lookup tables of two frames + monochrome - Select monochrome enhancement + pseudocolor - Select pseudocolor enhancement + rgb - Select true color mode (red, green, and blue frames) + window - Adjust the contrast and dc offset of the current frame + zoom - Zoom in on the image (change magnification) diff --git a/pkg/images/tv/iis/iis.par b/pkg/images/tv/iis/iis.par new file mode 100644 index 00000000..db706f09 --- /dev/null +++ b/pkg/images/tv/iis/iis.par @@ -0,0 +1 @@ +version,s,h,"Apr91" diff --git a/pkg/images/tv/iis/iism70/README b/pkg/images/tv/iis/iism70/README new file mode 100644 index 00000000..05f01307 --- /dev/null +++ b/pkg/images/tv/iis/iism70/README @@ -0,0 +1,5 @@ +IISM70 -- Device dependent interface subroutines for the IIS Model 70 image +display device. This package uses the ZFIOGD device driver, which is +responsible for physical i/o to the device. The source for the ZFIOGD driver +is in host$gdev; this driver must be compiled and installed in a system library +(libsys.a) before i/o to the IIS will work correctly. diff --git a/pkg/images/tv/iis/iism70/idsexpand.x b/pkg/images/tv/iis/iism70/idsexpand.x new file mode 100644 index 00000000..da2a172d --- /dev/null +++ b/pkg/images/tv/iis/iism70/idsexpand.x @@ -0,0 +1,30 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <gki.h> +include "../lib/ids.h" +include "iis.h" + +# IDS_EXPAND -- expand FRAME/BITPL if first element is IDS_EOD +# if the frames are not counted in order, as on the Model 75, +# that should be dealt with here (use the "flag" boolean). + +procedure ids_expand(data, max, flag) + +short data[ARB] # data +short max # max number of frames/bitplanes +bool flag # true if frames ... e.g. for Model 75 + +int i + +begin + if ( data[1] != IDS_EOD ) + return + do i = 1, max { + data[i] = i + } + if ( flag) { + data[1+max] = GRCHNUM + data[2+max] = IDS_EOD + } else + data[1+max] = IDS_EOD +end diff --git a/pkg/images/tv/iis/iism70/iis.com b/pkg/images/tv/iis/iism70/iis.com new file mode 100644 index 00000000..25a69d38 --- /dev/null +++ b/pkg/images/tv/iis/iism70/iis.com @@ -0,0 +1,12 @@ +# Common for IIS display + +int iischan # The device channel used by FIO +int iisnopen # Number of times the display has been opened +int iframe, iplane # frame, bitplanes to read/write +int i_frame_on # Which frame is on...cursor readback +short hdr[LEN_IISHDR] # Header +short zoom[16] # zoom for each plane +short xscroll[16] # scroll position for each plane +short yscroll[16] +common /iiscom/iischan, iisnopen, iframe, iplane, i_frame_on, + hdr, zoom, xscroll, yscroll diff --git a/pkg/images/tv/iis/iism70/iis.h b/pkg/images/tv/iis/iism70/iis.h new file mode 100644 index 00000000..96bb8b39 --- /dev/null +++ b/pkg/images/tv/iis/iism70/iis.h @@ -0,0 +1,120 @@ +# This file contains the hardware definitions for the iis model 70/f +# at Kitt Peak. + +# Define header +define LEN_IISHDR 8 # Length of IIS header + +define XFERID $1[1] # transfer id +define THINGCT $1[2] # thing count +define SUBUNIT $1[3] # subuint select +define CHECKSUM $1[4] # check sum +define XREG $1[5] # x register +define YREG $1[6] # y register +define ZREG $1[7] # z register +define TREG $1[8] # t register + +# Transfer ID definitions +define IREAD 100000B +define IWRITE 0B +define PACKED 40000B +define BYPASSIFM 20000B +define BYTE 10000B +define ADDWRITE 4000B +define ACCUM 2000B +define BLOCKXFER 1000B +define VRETRACE 400B +define MUX32 200B + +# Subunits +define REFRESH 1 +define LUT 2 +define OFM 3 +define IFM 4 +define FEEDBACK 5 +define SCROLL 6 +define VIDEOM 7 +define SUMPROC 8 +define GRAPHICS 9 +define CURSOR 10 +define ALU 11 +define ZOOM 12 +define IPB 15 + +# Command definitions +define COMMAND 100000B +define ADVXONTC 100000B # Advance x on thing count +define ADVXONYOV 40000B # Advance x on y overflow +define ADVYONXOV 100000B # Advance y on x overflow +define ADVYONTC 40000B # Advance y on thing count +define ERASE 100000B # Erase + +# 4 - Button Trackball +define PUSH 40000B +define BUTTONA 400B +define BUTTONB 1000B +define BUTTONC 2000B +define BUTTOND 4000B + +# Display channels +define CHAN1 1B +define CHAN2 2B +define CHAN3 4B +define CHAN4 10B +define ALLCHAN 17B +define GRCHAN 100000B +define GRCHNUM 16 + +define LEN_IISFRAMES 4 +define IISFRAMES CHAN1, CHAN2, CHAN3, CHAN4 + +# Center coordinates for zoom/scroll +define IIS_XCEN 256 +define IIS_YCEN 255 +# Inverted Y center is just IIS_YDIM - IIS_YCEN +define IIS_YCEN_INV 256 + +# Colors + +# these are bit plane mappings +define BLUE 1B +define GREEN 2B +define RED 4B +define MONO 7B +# next colors used by snap code ... used as array indexes. +define BLU 1 +define GR 2 +define RD 3 + + +# Bit plane selections +define BITPL0 1B +define BITPL1 2B +define BITPL2 4B +define BITPL3 10B +define BITPL4 20B +define BITPL5 40B +define BITPL6 100B +define BITPL7 200B +define ALLBITPL 377B + +# IIS Sizes +define IIS_XDIM 512 +define IIS_YDIM 512 +define MCXSCALE 64 # Metacode x scale +define MCYSCALE 64 # Metacode y scale +define SZB_IISHDR 16 # Size of IIS header in bytes +define LEN_ZOOM 3 # Zoom parameters +define LEN_CURSOR 3 # Cursor parameters +define LEN_SELECT 12 # frame select +define LEN_LUT 256 # Look up table +define LEN_OFM 1024 # Output function look up table +define LEN_IFM 8192 # Input function look up table +define LEN_VIDEOM 2048 # videometer output memory +define LEN_GRAM 256 # graphics ram +define MAXX 512 # maximum x register + 1 + +# IIS Status Words +define IIS_FILSIZE (IIS_XDIM * IIS_YDIM * SZB_CHAR) +define IIS_BLKSIZE 1 +define IIS_OPTBUFSIZE 32768 +define IIS_MAXBUFSIZE 32768 diff --git a/pkg/images/tv/iis/iism70/iisbutton.x b/pkg/images/tv/iis/iism70/iisbutton.x new file mode 100644 index 00000000..50dfff7b --- /dev/null +++ b/pkg/images/tv/iis/iism70/iisbutton.x @@ -0,0 +1,44 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "iis.h" +include "../lib/ids.h" + +# IISBUTTON -- Read, button status + +procedure iisbutton (cnum, x, y, key) + +int cnum # cursor number +int x,y # coordinates +int key # key pressed + +short status +int and() + +include "iis.com" + +begin + call iishdr (IREAD, 1, CURSOR+COMMAND, 0, 0, 0, 0) + call iisio (status, 1 * SZB_CHAR) + + if ( cnum == IDS_BUT_WT ) { + while ( and (int(status), PUSH) == 0 ) { + call tsleep(1) + call iisio (status, 1 * SZB_CHAR) + } + } + + if ( and ( int(status), PUSH) == 0 ) + key = 0 + else { + status = and ( int(status), 7400B) / 256 + switch(status) { + case 4: + status = 3 + + case 8: + status = 4 + } + key = status + } +end diff --git a/pkg/images/tv/iis/iism70/iiscls.x b/pkg/images/tv/iis/iism70/iiscls.x new file mode 100644 index 00000000..c717f636 --- /dev/null +++ b/pkg/images/tv/iis/iism70/iiscls.x @@ -0,0 +1,27 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <knet.h> +include "iis.h" + +define LEN_HID 5 + +# IISCLS -- Close IIS display. + +procedure iiscls (chan, status) + +int chan[ARB] +int status + +include "iis.com" + +begin + # first we need to tuck away the constants for zoom and scroll + # as we cannot read them on the model 70. Would that there were + # somewhere to put them. Alas not. So just drop them on the floor. + + if (iisnopen == 1) { + call zclsgd (iischan, status) + iisnopen = 0 + } +end diff --git a/pkg/images/tv/iis/iism70/iiscursor.x b/pkg/images/tv/iis/iism70/iiscursor.x new file mode 100644 index 00000000..5ffc9131 --- /dev/null +++ b/pkg/images/tv/iis/iism70/iiscursor.x @@ -0,0 +1,108 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "iis.h" +include "../lib/ids.h" + +# cscale makes 0-32767 range from 0-62. The 62 results from the need +# to describe a cursor with a center, and hence an ODD number of points. +# Thus, we pretend the cursor ranges from 0-62 rather than 0-63, and +# the center is at (31,31). +# cwidth describes the (cursor) ram width, which is 64 ( by 64). + +define CSCALE 528 +define CWIDTH 64 +define CSIZE 4096 + +# IISCURSOR -- Read, Write cursor shape, turn cursor on/off + +procedure iiscursor (rw, cur, n, data) + +short rw # read or write +short cur # cursor number ... ignored for IIS M70 +short n # number of data values +short data[ARB] # the data + +short command, len +short shape[CSIZE] +short status +int rate +int i,j,index +int mod(), and(), or(), andi() + +include "iis.com" + +begin + len = 1 + if (data[1] != IDS_CSHAPE) { + call iishdr (IREAD, len, CURSOR+COMMAND, 0, 0, 0, 0) + call iisio (status, len * SZB_CHAR) + } + + if (rw == IDS_WRITE) + command = andi (IWRITE+VRETRACE, 177777B) + else + command = andi (IREAD+VRETRACE, 177777B) + + if (data[1] != IDS_CSHAPE){ + if (rw == IDS_WRITE) { + switch (data[1]) { + case IDS_OFF: + status = and(int(status), 177776B) + + case IDS_ON: + status = or (int(status), 1) + + case IDS_CBLINK: + rate = mod (int(data[2])-1, 4) * 8 + status = or (rate, and (int(status),177747B)) + } + call iishdr (command, len, CURSOR+COMMAND, 0, 0, 0, 0) + call iisio (status, len * SZB_CHAR) + } else { + if ( data[1] == IDS_CBLINK ) + data[2] = ( and (int(status), 30B) / 8 ) + 1 + else if ( and ( int(status), 1) == 0 ) + data[1] = IDS_OFF + else + data[1] = IDS_ON + } + + } else { + # deal with cursor shape. + + len = CSIZE + if ( rw == IDS_WRITE) { + call aclrs (shape, CSIZE) + for ( i = 2 ; i <= n-1 ; i = i + 2 ) { + # given GKI data pairs for x,y cursor_on bits, set shape datum + # the first value is x, then y + if (data[i] == IDS_EOD) + break + j = data[i]/CSCALE + index = (data[i+1]/CSCALE) * CWIDTH + j + 1 + shape[index] = 1 + } + } + + call iishdr (command, len, CURSOR, ADVXONTC, ADVYONXOV, 0, 0) + call iisio (shape, len * SZB_CHAR) + + # if read command, return all set bits as GKI x,y pairs + if ( rw != IDS_WRITE) { + i = 2 + for ( j = 1 ; j <= CSIZE ; j = j + 1 ) { + if ( shape[j] != 0 ) { + data[i] = mod(j,CWIDTH) * CSCALE + data[i+1] = (j/CWIDTH) * CSCALE + i = i + 2 + if ( i > n-1 ) + break + } + } + if ( i <= n ) + data[i] = IDS_EOD + n = i + } + } +end diff --git a/pkg/images/tv/iis/iism70/iishdr.x b/pkg/images/tv/iis/iism70/iishdr.x new file mode 100644 index 00000000..bf22d493 --- /dev/null +++ b/pkg/images/tv/iis/iism70/iishdr.x @@ -0,0 +1,31 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "iis.h" + +# IISHDR -- Form IIS header. + +procedure iishdr (id, count, subunit, x, y, z, t) + +int id, count, subunit, x, y, z, t +int i, sum +include "iis.com" + +begin + XFERID(hdr) = id + THINGCT(hdr) = count + SUBUNIT(hdr) = subunit + XREG(hdr) = x + YREG(hdr) = y + ZREG(hdr) = z + TREG(hdr) = t + CHECKSUM(hdr) = 1 + + if (THINGCT(hdr) > 0) + THINGCT(hdr) = -THINGCT(hdr) + + sum = 0 + for (i = 1; i <= LEN_IISHDR; i = i + 1) + sum = sum + hdr[i] + CHECKSUM(hdr) = -sum +end diff --git a/pkg/images/tv/iis/iism70/iishisto.x b/pkg/images/tv/iis/iism70/iishisto.x new file mode 100644 index 00000000..374342a0 --- /dev/null +++ b/pkg/images/tv/iis/iism70/iishisto.x @@ -0,0 +1,53 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "iis.h" +include "../lib/ids.h" + +# IISHISTO -- Activate, Read histogram. + +procedure iishisto (rw, color, offset, a_n, data) + +short rw # read or write +short color[ARB] # color(s) to write +short offset # offset into histogram table +short a_n # number of data values +short data[ARB] # the data + +int n, command, off, len, x, y, z +include "iis.com" + +begin + n = a_n + if (n < 1) + return + + # set the area to be histogrammed ... in data[1], currently + # device very specific ( 2 == whole region) . Need to fix this + # perhaps via specific graph plane filled with gkifill command to + # depict area desired. + # n must be twice the number of datum values. Upper level code + # must know this to leave enough room. Would be better if upper + # code could ignore this (fact). + + if (rw == IDS_WRITE) { + command = IWRITE+VRETRACE + x = 0 + y = 0 + z = 0 + len = 1 + data[1] = 2 + call iishdr (command, len, VIDEOM+COMMAND, x, y, z, 0) + call iisio (data[1], len * SZB_CHAR) + return + } + + off = offset + command = IREAD+VRETRACE + len = min (n, LEN_VIDEOM-off+1) + off = min (LEN_VIDEOM, off) - 1 + y = off/MAXX + ADVYONXOV + x = mod (off, MAXX) + ADVXONTC + call iishdr (command, len, VIDEOM, x, y, z, 0) + call iisio (data, len * SZB_CHAR) +end diff --git a/pkg/images/tv/iis/iism70/iisifm.x b/pkg/images/tv/iis/iism70/iisifm.x new file mode 100644 index 00000000..ef04a1be --- /dev/null +++ b/pkg/images/tv/iis/iism70/iisifm.x @@ -0,0 +1,51 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "iis.h" +include "../lib/ids.h" + +define LUT_IMAX 255 + +# IISIFM -- Read and Write INPUT look up table. +# Written data is from line end points, read data +# is full array. + +procedure iisifm (rw, offset, n, data) + +short rw # read or write +short offset # offset into lut +short n # number of data values +short data[ARB] # the data + +int command,len,x,y +pointer sp, idata + +include "iis.com" + +begin + if ( rw == IDS_WRITE) { + if (n < 4) + return + + call smark (sp) + call salloc (idata, LEN_IFM, TY_SHORT) + call aclrs (Mems[idata], LEN_IFM) + + command = IWRITE+VRETRACE + call idslfill (data, int(n), Mems[idata], LEN_IFM, 0, LUT_IMAX) + len = LEN_IFM + } else { + len = n + command = IREAD+VRETRACE + } + + y = ADVYONXOV + x = ADVXONTC + call iishdr (command, len, IFM, x, y, 0, 0) + + if (rw == IDS_WRITE) { + call iisio (Mems[idata], len * SZB_CHAR) + call sfree (sp) + } else + call iisio (data, len * SZB_CHAR) +end diff --git a/pkg/images/tv/iis/iism70/iisio.x b/pkg/images/tv/iis/iism70/iisio.x new file mode 100644 index 00000000..f8e005c6 --- /dev/null +++ b/pkg/images/tv/iis/iism70/iisio.x @@ -0,0 +1,35 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <knet.h> +include "iis.h" + +# IISIO -- Read/Write to IIS. + +procedure iisio (buf, nbytes) + +short buf[ARB] +int nbytes + +int nbites +int and() + +include "iis.com" + +begin + call iiswt (iischan, nbites) + if (nbites == ERR) + return + + call zawrgd (iischan, hdr, SZB_IISHDR, 0) + call iiswt (iischan, nbites) + if (nbites == ERR) + return + + if (and (int(XFERID(hdr)), IREAD) != 0) + call zardgd (iischan, buf, nbytes, 0) + else + call zawrgd (iischan, buf, nbytes, 0) + + call iiswt (iischan, nbites) +end diff --git a/pkg/images/tv/iis/iism70/iislut.x b/pkg/images/tv/iis/iism70/iislut.x new file mode 100644 index 00000000..07819247 --- /dev/null +++ b/pkg/images/tv/iis/iism70/iislut.x @@ -0,0 +1,67 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "iis.h" +include "../lib/ids.h" + +define LUT_LMAX 255 + +# IISLUT -- Read and Write look up table. +# NOTE the ASYMMETRY ... written data is derived from end +# points, but read data is the full array (see zsnapinit, +# for instance, for read usage.) + +procedure iislut (rw, frame, color, offset, n, data) + +short rw # read or write +short frame[ARB] # frame array +short color[ARB] # color array +short offset # offset into lut +short n # number of data values +short data[ARB] # the data + +int command,len,x,y,z,t +short iispack() +int mapcolor() +pointer sp, ldata + +include "iis.com" + +begin + z = mapcolor (color) + t = iispack(frame) + if (t == GRCHAN) { + return + } + + if ( rw == IDS_WRITE) { + if ( n < 4) + return + command = IWRITE+VRETRACE + + # data space for manipulating lut information + + call smark (sp) + call salloc (ldata, LEN_LUT, TY_SHORT) + call aclrs (Mems[ldata], LEN_LUT) + + # We could have negative lut values, but don't bother for now + call idslfill (data, int(n), Mems[ldata], LEN_LUT, 0, LUT_LMAX) + + len = LEN_LUT + } else { + len = n + command = IREAD+VRETRACE + } + + x = ADVXONTC + y = 0 + + call iishdr (command, len, LUT, x, y, z, t) + + if ( rw == IDS_WRITE) { + call iisio (Mems[ldata], len * SZB_CHAR) + call sfree (sp) + } else + call iisio (data, len * SZB_CHAR) +end diff --git a/pkg/images/tv/iis/iism70/iismatch.x b/pkg/images/tv/iis/iism70/iismatch.x new file mode 100644 index 00000000..a2435fdc --- /dev/null +++ b/pkg/images/tv/iis/iism70/iismatch.x @@ -0,0 +1,76 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "iis.h" +include "../lib/ids.h" + +# IISMATCH -- copy (match) a set of look up tables to a given table; +# frames/color specify the given table, data gives frame/color for +# set to be changed. + +procedure iismatch (code, frames, color, n, data) + +short code # which table type +short frames[ARB] # reference frame +short color[ARB] # reference color +short n # count of data items +short data[ARB] # frame/color to be changed. + +pointer sp, ldata +int len, x,y,z,t +int unit, i +int mapcolor(), ids_dcopy() +short temp[IDS_MAXIMPL+1] +short iispack() + +include "../lib/ids.com" + +begin + switch (code) { + case IDS_FRAME_LUT: + len = LEN_LUT + x = ADVXONTC + y = 0 + z = mapcolor (color) + t = iispack (frames) + if (t == GRCHAN) + return + unit = LUT + + case IDS_OUTPUT_LUT: + len = LEN_OFM + x = ADVXONTC + y = ADVYONXOV + z = mapcolor (color) + t = 0 + + default: + return + } + + call smark (sp) + call salloc (ldata, len, TY_SHORT) + + call iishdr (IREAD+VRETRACE, len, unit, x, y, z, t) + call iisio (Mems[ldata], len * SZB_CHAR) + + i = ids_dcopy (data, temp) + switch (code) { + case IDS_FRAME_LUT: + call ids_expand (temp, i_maxframes, true) + t = iispack (temp) + i = ids_dcopy (data[i+1], temp) + call ids_expand (temp, 3, false) # 3...max colors + z = mapcolor (temp) + + case IDS_OUTPUT_LUT: + i = ids_dcopy (data[i+1], temp) + call ids_expand (temp, 3, false) + z = mapcolor (temp) + } + + call iishdr (IWRITE+VRETRACE, len, unit, x, y, z, t) + call iisio (Mems[ldata], len * SZB_CHAR) + + call sfree (sp) +end diff --git a/pkg/images/tv/iis/iism70/iisminmax.x b/pkg/images/tv/iis/iism70/iisminmax.x new file mode 100644 index 00000000..22a3062e --- /dev/null +++ b/pkg/images/tv/iis/iism70/iisminmax.x @@ -0,0 +1,87 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "iis.h" +include "../lib/ids.h" + +define LEN_MM 6 + +# IISMIN -- Read minimum registers + +procedure iismin (rw, color, n, data) + +short rw # read or write +short color[ARB] # color +short n # number of data values +short data[ARB] # the data + +int command,x +short const[LEN_MM] +int i,j + +include "iis.com" + +begin + if ( rw == IDS_WRITE) + return + command = IREAD+VRETRACE + x = ADVXONTC + call iishdr(command, LEN_MM, SUMPROC+COMMAND, x, 0, 0, 0) + call iisio (const, LEN_MM * SZB_CHAR) + j = 1 + for ( i = 1 ; i <= n ; i = i + 1 ) { + switch(color[j]) { + case IDS_RED: + data[i] = const[5] + + case IDS_GREEN: + data[i] = const[3] + + case IDS_BLUE: + data[i] = const[1] + } + j = j+1 + if ( color[j] == IDS_EOD ) + j = j - 1 + } +end + +# IISMAX -- Read maximum registers + +procedure iismax (rw, color, n, data) + +short rw # read or write +short color[ARB] # color +short n # number of data values +short data[ARB] # the data + +int command,x +short const[LEN_MM] +int i,j + +include "iis.com" + +begin + if ( rw == IDS_WRITE) + return + command = IREAD+VRETRACE + x = ADVXONTC + call iishdr(command, LEN_MM, SUMPROC+COMMAND, x, 0, 0, 0) + call iisio (const, LEN_MM * SZB_CHAR) + j = 1 + for ( i = 1 ; i <= n ; i = i + 1 ) { + switch(color[j]) { + case IDS_RED: + data[i] = const[6] + + case IDS_GREEN: + data[i] = const[4] + + case IDS_BLUE: + data[i] = const[2] + } + j = j+1 + if ( color[j] == IDS_EOD ) + j = j - 1 + } +end diff --git a/pkg/images/tv/iis/iism70/iisoffset.x b/pkg/images/tv/iis/iism70/iisoffset.x new file mode 100644 index 00000000..d7f618dc --- /dev/null +++ b/pkg/images/tv/iis/iism70/iisoffset.x @@ -0,0 +1,67 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "iis.h" +include "../lib/ids.h" + +define LEN_CONST 3 + +# IISOFFSET -- Read and Write output bias registers + +procedure iisoffset (rw, color, n, data) + +short rw # read or write +short color[ARB] # color +short n # number of data values +short data[ARB] # the data + +int command,len,x +short const[3] +int i,j + +include "iis.com" + +begin + command = IREAD+VRETRACE + x = 8 + ADVXONTC + len = LEN_CONST + call iishdr(command, len, SUMPROC+COMMAND, x, 0, 0, 0) + call iisio (const, len * SZB_CHAR) + if ( rw == IDS_WRITE) { + command = IWRITE+VRETRACE + j = 1 + for ( i =1 ; color[i] != IDS_EOD ; i = i + 1) { + switch(color[i]) { + case IDS_RED: + const[3] = data[j] + + case IDS_GREEN: + const[2] = data[j] + + case IDS_BLUE: + const[1] = data[j] + } + if ( j < n) + j = j + 1 + } + call iishdr (command, len, SUMPROC+COMMAND, x, 0, 0, 0) + call iisio (const, len * SZB_CHAR) + } else { + j = 1 + for ( i = 1 ; i <= n ; i = i + 1 ) { + switch(color[j]) { + case IDS_RED: + data[i] = const[3] + + case IDS_GREEN: + data[i] = const[2] + + case IDS_BLUE: + data[i] = const[1] + } + j = j+1 + if ( color[j] == IDS_EOD ) + j = j - 1 + } + } +end diff --git a/pkg/images/tv/iis/iism70/iisofm.x b/pkg/images/tv/iis/iism70/iisofm.x new file mode 100644 index 00000000..0c19c117 --- /dev/null +++ b/pkg/images/tv/iis/iism70/iisofm.x @@ -0,0 +1,53 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "iis.h" +include "../lib/ids.h" + +define LUT_OMAX 1023 + +# IISOFM -- Read and Write OUTPUT look up table. +# Written data is from end points, read data is full +# array. + +procedure iisofm (rw, color, offset, n, data) + +short rw # read or write +short color[ARB] # color(s) to write +short offset # offset into lut +short n # number of data values +short data[ARB] # the data + +int command,len,x,y,z +int mapcolor() +pointer sp, odata + +include "iis.com" + +begin + z = mapcolor (color) + if ( rw == IDS_WRITE) { + if (n < 4) + return + + call smark (sp) + call salloc (odata, LEN_OFM, TY_SHORT) + call aclrs (Mems[odata], LEN_OFM) + + command = IWRITE+VRETRACE + call idslfill (data, int(n), Mems[odata], LEN_OFM, 0, LUT_OMAX) + len = LEN_OFM + } + else { + len = n + command = IREAD+VRETRACE + } + y = ADVYONXOV + x = ADVXONTC + call iishdr (command, len, OFM, x, y, z, 0) + if (rw == IDS_WRITE) { + call iisio (Mems[odata], len * SZB_CHAR) + call sfree (sp) + } else + call iisio (data, len * SZB_CHAR) +end diff --git a/pkg/images/tv/iis/iism70/iisopn.x b/pkg/images/tv/iis/iism70/iisopn.x new file mode 100644 index 00000000..29335c62 --- /dev/null +++ b/pkg/images/tv/iis/iism70/iisopn.x @@ -0,0 +1,35 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <knet.h> +include "iis.h" + +# IISOPN -- Open IIS display. + +procedure iisopn (devinfo, mode, chan) + +char devinfo[ARB] # device info for zopen +int mode # access mode +int chan[ARB] # receives IIS descriptor + +bool first_time +data first_time /true/ +include "iis.com" + +begin + if (first_time) { + iisnopen = 0 + first_time = false + } + + # We permit multiple opens but only open the physical device once. + if (iisnopen == 0) + call zopngd (devinfo, mode, iischan) + + if (iischan == ERR) + chan[1] = ERR + else { + iisnopen = iisnopen + 1 + chan[1] = iischan + } +end diff --git a/pkg/images/tv/iis/iism70/iispack.x b/pkg/images/tv/iis/iism70/iispack.x new file mode 100644 index 00000000..4c2c70f3 --- /dev/null +++ b/pkg/images/tv/iis/iism70/iispack.x @@ -0,0 +1,21 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../lib/ids.h" + +# IISPACK -- Pack color or frame data into a single word. + +short procedure iispack (data) + +short data[ARB] +int value, bit, i +int or() + +begin + value = 0 + for (i=1; data[i] != IDS_EOD; i=i+1) { + bit = data[i] - 1 + value = or (value, 2 ** bit) + } + + return (value) +end diff --git a/pkg/images/tv/iis/iism70/iispio.x b/pkg/images/tv/iis/iism70/iispio.x new file mode 100644 index 00000000..f8c57138 --- /dev/null +++ b/pkg/images/tv/iis/iism70/iispio.x @@ -0,0 +1,65 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <knet.h> +include "iis.h" + +# IISPIO -- Pixel i/o to the IIS. + +procedure iispio (buf, ny) + +short buf[IIS_XDIM,ny] # Cell array +int ny # number of image lines + +pointer iobuf +bool first_time +int xferid, status, npacked, szline, i +int and() +include "iis.com" +data first_time /true/ + +begin + if (first_time) { + call malloc (iobuf, IIS_MAXBUFSIZE, TY_CHAR) + first_time = false + } + + # Wait for the last i/o transfer. + call iiswt (iischan, status) + if (status == ERR) + return + + # Transmit the packet header. + call zawrgd (iischan, hdr, SZB_IISHDR, 0) + call iiswt (iischan, status) + if (status == ERR) + return + + # Read or write the data block. + npacked = ny * IIS_XDIM + szline = IIS_XDIM / (SZ_SHORT * SZB_CHAR) + + # Transmit the data byte-packed to increase the i/o bandwith + # when using network i/o. + + xferid = XFERID(hdr) + if (and (xferid, IREAD) != 0) { + # Read from the IIS. + + call zardgd (iischan, Memc[iobuf], npacked, 0) + call iiswt (iischan, status) + + # Unpack and line flip the packed data. + do i = 0, ny-1 + call achtbs (Memc[iobuf+i*szline], buf[1,ny-i], IIS_XDIM) + + } else { + # Write to the IIS. + + # Bytepack the image lines, doing a line flip in the process. + do i = 0, ny-1 + call achtsb (buf[1,ny-i], Memc[iobuf+i*szline], IIS_XDIM) + + call zawrgd (iischan, Memc[iobuf], npacked, 0) + } +end diff --git a/pkg/images/tv/iis/iism70/iisrange.x b/pkg/images/tv/iis/iism70/iisrange.x new file mode 100644 index 00000000..8fad856b --- /dev/null +++ b/pkg/images/tv/iis/iism70/iisrange.x @@ -0,0 +1,97 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "iis.h" +include "../lib/ids.h" + +define LEN_RANGE 1 + +# IISRANGE -- Read and write range scaling registers +# Input data is of form 1-->range "0", 2,3 --> "1", 4-7 --> "2" +# and anything beyond 7 --> "4". This is just like zoom. +# However, on readback, the actual range values are returned. If +# this should change, the zsnapinit code must change too (the only +# place where a range read is done). + +procedure iisrange (rw, color, n, data) + +short rw # read or write +short color[ARB] # color +short n # number of data values +short data[ARB] # the data + +short range +int i, j +int command, x, itemp, ival +int and(), or() +include "iis.com" + +begin + if (data[1] == IDS_EOD) + return + + command = IREAD + x = ADVXONTC + + call iishdr (command, LEN_RANGE, OFM+COMMAND, x, 0, 0, 0) + call iisio (range, LEN_RANGE * SZB_CHAR) + + if (rw == IDS_WRITE) { + command = IWRITE+VRETRACE + j = 1 + for (i=1; color[i] != IDS_EOD; i=i+1) { + switch (data[j]) { + case 1,2: + ival = data[j]-1 + case 3: + ival = 1 + case 4,5,6,7: + ival = 2 + + default: + if (ival < 0) + ival = 0 + else + ival = 3 + } + + itemp = range + switch(color[i]) { + case IDS_RED: + range = or (ival*16, and (itemp, 17B)) + + case IDS_GREEN: + range = or (ival*4, and (itemp, 63B)) + + case IDS_BLUE: + range = or (ival, and (itemp, 74B)) + } + + if ( j < n) + j = j + 1 + } + + call iishdr (command, LEN_RANGE, OFM+COMMAND, x, 0, 0, 0) + call iisio (range, LEN_RANGE * SZB_CHAR) + + } else { + # Return a range value + j = 1 + for (i=1; i <= n; i=i+1) { + itemp = range + switch (color[j]) { + case IDS_RED: + data[i] = and (itemp, 60B) / 16 + + case IDS_GREEN: + data[i] = and (itemp, 14B) / 4 + + case IDS_BLUE: + data[i] = and (itemp, 3B) + } + j = j+1 + if (color[j] == IDS_EOD) + j = j - 1 + } + } +end diff --git a/pkg/images/tv/iis/iism70/iisrd.x b/pkg/images/tv/iis/iism70/iisrd.x new file mode 100644 index 00000000..20e99cb2 --- /dev/null +++ b/pkg/images/tv/iis/iism70/iisrd.x @@ -0,0 +1,51 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "iis.h" + +# IISRD -- Read data from IIS. Reads are packed when can. +# The data is line-flipped. + +procedure iisrd (chan, buf, nbytes, offset) + +int chan[ARB] +short buf[ARB] +int nbytes +long offset + +long off1, off2 +int nchars, thing_count, tid, y1, y2, x +int or() +include "iis.com" + +begin + # Convert to chars and clip at the top of the display. + off1 = (offset - 1) / SZB_CHAR + 1 + off2 = min (IIS_XDIM * IIS_YDIM, (offset + nbytes - 1) / SZB_CHAR) + 1 + nchars = off2 - off1 + + y1 = (off1-1 ) / IIS_XDIM + y2 = (off2-1 - IIS_XDIM) / IIS_XDIM + y2 = max (y1,y2) + + # Pack only if start at x=0 + x = (off1 - 1) - y1 * IIS_XDIM + if ( x == 0 ) + tid = IREAD+PACKED + else + tid = IREAD + + # If only a few chars, don't pack...have trouble with count of 1 + # and this maeks code same as iiswr.x + if ( nchars < 4 ) + tid = IREAD + + thing_count = nchars + + call iishdr (tid, thing_count, REFRESH, + or (x, ADVXONTC), or (IIS_YDIM-1-y2, ADVYONXOV), iframe, iplane) + if ( tid == IREAD) + call iisio (buf, nbytes) + else + call iispio (buf, y2 - y1 + 1) +end diff --git a/pkg/images/tv/iis/iism70/iisscroll.x b/pkg/images/tv/iis/iism70/iisscroll.x new file mode 100644 index 00000000..a583e4a4 --- /dev/null +++ b/pkg/images/tv/iis/iism70/iisscroll.x @@ -0,0 +1,101 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <gki.h> +include "iis.h" +include "../lib/ids.h" + +# IISSCROLL -- Read and Write scroll registers +# We scroll multiple frames to multiple centers; if there are not +# enough data pairs to match the number of frames, use the last +# pair repeatedly. + +procedure iisscroll (rw, frame, n, data) + +short rw # read or write +short frame[ARB] # frame data +short n # number of data values +short data[ARB] # the data + +int z +short iispack() +int i,total, pl, index + +include "iis.com" + +begin + total = n/2 + if ( rw != IDS_WRITE) { + # Scroll registers are write only + do i = 1, total { + pl = frame[i] + if (pl == IDS_EOD) + break + data[2*i-1] = xscroll[pl] * MCXSCALE + data[2*i] = yscroll[pl] * MCYSCALE + } + + if (2*total < n) + data[2*total+1] = IDS_EOD + return + } + + # Set all the scroll offsets. + index = 1 + for (i=1; frame[i] != IDS_EOD; i=i+1) { + pl = frame[i] + xscroll[pl] = data[2*index-1] / MCXSCALE + yscroll[pl] = data[2*index ] / MCYSCALE + if (i < total) + index = index + 1 + } + + # Now do the scrolling. + for (i=1; frame[i] != IDS_EOD; i=i+1) { + pl = frame[i] + if (i == total) { + z = iispack (frame[i]) + call do_scroll (z, xscroll[pl], yscroll[pl]) + break + } else + call do_scroll (short(2**(pl-1)), xscroll[pl], yscroll[pl]) + } +end + + +procedure do_scroll (planes, x, y) + +short planes # bit map for planes +short x,y # where to scroll + +short command +short scr[2] +short xs,ys + +include "iis.com" + +begin + xs = x + ys = y + command = IWRITE+VRETRACE + scr[1] = xs + scr[2] = ys + + # If x/y scroll at "center", scr[1/2] are now IIS_[XY]CEN + # y = 0 is at top for device while y = 1 is bottom for user + # so for y, center now moves to IIS_YCEN_INV !! + + scr[2] = IIS_YDIM - 1 - scr[2] + + # Scroll is given for center, but hardware wants corner coords. + scr[1] = scr[1] - IIS_XCEN + scr[2] = scr[2] - IIS_YCEN_INV + + if (scr[1] < 0) + scr[1] = scr[1] + IIS_XDIM + if (scr[2] < 0) + scr[2] = scr[2] + IIS_YDIM + + call iishdr (command, 2, SCROLL, ADVXONTC, 0, int(planes), 0) + call iisio (scr, 2 * SZB_CHAR) +end diff --git a/pkg/images/tv/iis/iism70/iissplit.x b/pkg/images/tv/iis/iism70/iissplit.x new file mode 100644 index 00000000..2badb7cb --- /dev/null +++ b/pkg/images/tv/iis/iism70/iissplit.x @@ -0,0 +1,68 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "iis.h" +include "../lib/ids.h" + +define X_SPLIT 12 + +# IISSPLIT -- Read and Write split screen coordinates + +procedure iissplit (rw, n, data) + +short rw # read or write +short n # number of data values +short data[ARB] # the data + +int command,len,x +short coord[2] + +include "iis.com" + +begin + len = min (int(n), 2) + if ( len < 1) { + data[1] = IDS_EOD + return + } + + if (rw == IDS_WRITE) { + if (data[1] == IDS_EOD) + return + command = IWRITE+VRETRACE + coord[1] = data[1] / MCXSCALE + + + # Split screen will display the full screen from one lut ONLY + # if the split coordinate is zero. Setting the split to 511 + # means that all the screen BUT the last pixel is from one lut. + # Hence the y coordinate for full screen in one quad is + # (device) 0 , (user) 511. If the user requests split at (0,0), + # we honor this as a (device) (0,0). This will remove the + # ability to split the screen with just the bottom line + # in the "other" lut, which shouldn't bother anyone. + + if (len == 2) + coord[2] = (IIS_YDIM - 1) - data[2]/MCYSCALE + + if (coord[2] == IIS_YDIM - 1) + coord[2] = 0 + + } else + command = IREAD+VRETRACE + + # at most, read/write the x,y registers + x = X_SPLIT + ADVXONTC + + call iishdr (command, len, LUT+COMMAND, x, 0, 0, 0) + call iisio (coord, len * SZB_CHAR) + + if ( rw != IDS_WRITE ) { + data[1] = coord[1] * MCXSCALE + if ( len == 2 ) { + if ( coord[2] == 0) + coord[2] = IIS_YDIM - 1 + data[2] = (IIS_YDIM - 1 - coord[2] ) * MCYSCALE + } + } +end diff --git a/pkg/images/tv/iis/iism70/iistball.x b/pkg/images/tv/iis/iism70/iistball.x new file mode 100644 index 00000000..ebcc6566 --- /dev/null +++ b/pkg/images/tv/iis/iism70/iistball.x @@ -0,0 +1,41 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "iis.h" +include "../lib/ids.h" + +# IISTBALL -- Read, Write tball status to turn tball on/off + +procedure iistball (rw, data) + +short rw # read or write +short data[ARB] # the data + +int command,len +short status +int and(), or() + +include "iis.com" + +begin + len = 1 + call iishdr (IREAD, len, CURSOR+COMMAND, 0, 0, 0, 0) + call iisio (status, len * SZB_CHAR) + if ( rw == IDS_WRITE) { + command = IWRITE+VRETRACE + switch (data[1]) { + case IDS_OFF: + status = and (int(status), 177771B) + + case IDS_ON: + status = or ( int(status), 6) + } + call iishdr (command, 1, CURSOR+COMMAND, 0, 0, 0, 0) + call iisio (status, 1 * SZB_CHAR) + } else { + if ( and ( int(status), 6) == 0 ) + data[2] = IDS_OFF + else + data[2] = IDS_ON + } +end diff --git a/pkg/images/tv/iis/iism70/iiswr.x b/pkg/images/tv/iis/iism70/iiswr.x new file mode 100644 index 00000000..11bb2803 --- /dev/null +++ b/pkg/images/tv/iis/iism70/iiswr.x @@ -0,0 +1,51 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "iis.h" + +# IISWR -- Write pixel data to IIS. Writes are packed with full lines only. +# The data is line-flipped, causing the first line to be displayed at the bottom +# of the screen. + +procedure iiswr (chan, buf, nbytes, offset) + +int chan[ARB] +short buf[ARB] +int nbytes +long offset + +long off1, off2 +int nchars, thing_count, tid, y1, y2, x +int or() +include "iis.com" + +begin + # Convert to chars and clip at the top of the display. + off1 = (offset - 1) / SZB_CHAR + 1 + off2 = min (IIS_XDIM * IIS_YDIM, (offset + nbytes - 1) / SZB_CHAR) + 1 + nchars = off2 - off1 + + y1 = (off1-1 ) / IIS_XDIM + y2 = (off2-1 - IIS_XDIM) / IIS_XDIM + y2 = max (y1,y2) + + # Pack only if full lines + x = (off1 - 1) - y1 * IIS_XDIM + if ( x == 0 ) + tid = IWRITE+BYPASSIFM+PACKED+BLOCKXFER+BYTE + else + tid = IWRITE+BYPASSIFM + + # If only a few chars, don't pack (BLOCKXFER needs nchar>=4) + if ( nchars < 4 ) + tid = IWRITE+BYPASSIFM + + thing_count = nchars + + call iishdr (tid, thing_count, REFRESH, + or (x, ADVXONTC), or (IIS_YDIM-1-y2, ADVYONXOV), iframe, iplane) + if ( tid == IWRITE+BYPASSIFM) + call iisio (buf, nbytes) + else + call iispio (buf, y2 - y1 + 1) +end diff --git a/pkg/images/tv/iis/iism70/iiswt.x b/pkg/images/tv/iis/iism70/iiswt.x new file mode 100644 index 00000000..93f1e04a --- /dev/null +++ b/pkg/images/tv/iis/iism70/iiswt.x @@ -0,0 +1,18 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <knet.h> +include "iis.h" + +# IISWT -- Wait for IIS display. + +procedure iiswt (chan, nbytes) + +int chan[ARB] +int nbytes +include "iis.com" + +begin + call zawtgd (iischan, nbytes) + nbytes = nbytes * SZB_CHAR +end diff --git a/pkg/images/tv/iis/iism70/iiszoom.x b/pkg/images/tv/iis/iism70/iiszoom.x new file mode 100644 index 00000000..d703beec --- /dev/null +++ b/pkg/images/tv/iis/iism70/iiszoom.x @@ -0,0 +1,98 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "iis.h" +include "../lib/ids.h" + +# IISZOOM -- Read and Write zoom magnification and coordinates. +# the zoom coordinates give the point that should appear in the +# center of the screen. For the I2S model 70, this requires a +# scroll. In order for the scroll to be "determinable", we always +# set the I2S "zoom center" to (IIS_XCEN,IIS_YCEN_INV). The IIS_YCEN_INV +# results from specifying IIS_YCEN for y center and then having to "invert" y +# to put GKI(y) = 0 at bottom. +# This routine implements a command of the form "zoom these frames +# to the coordinates given, with each triple of data setting a +# zoom factor and a zoom center for the corresponding frame". +# If there are excess frames (rel. to "n"), use the last triple. + +procedure iiszoom (rw, frames, n, data) + +short rw # read or write +short frames[ARB] # which frames to zoom +short n # number of data values +short data[ARB] # the data + +int command,x +int i, total,pl,index +short zm,temp[4] +short scroll[2*IDS_MAXIMPL + 1] +short center[3] +# magnification, and "zoom center" +data temp /0,IIS_XCEN,IIS_YCEN_INV, 0/ +# center in GKI x=256 y=255 +data center/ 16384, 16320, 0/ + +include "iis.com" + +begin + total = n/3 + + if ( rw != IDS_WRITE) { + # hardware is write only + do i = 1, total { + index = (i-1) * 3 + 1 + pl = frames[i] + if ( pl == IDS_EOD) + break + data[index] = zoom[pl] + data[index+1] = xscroll[pl] * MCXSCALE + data[index+2] = yscroll[pl] * MCYSCALE + } + if ( 3*total < n) + data[index+3] = IDS_EOD + return + } + + # can't have in data statements as IDS_EOD == (-2) and + # fortran won't allow () in data statements!!! + + temp[4] = IDS_EOD + center[3] = IDS_EOD + command = IWRITE+VRETRACE + x = ADVXONTC + + # the model 70 zooms all frames together. So ignore "frames" + # argument here, though needed for subsequent scroll. + + zm = data[1] + if ( zm <= 1 ) + zm = 0 + else if (zm >= 8) + zm = 3 + else + switch(zm) { + case 2,3: + zm = 1 + + case 4,5,6,7: + zm = 2 + } + call amovks(short(2**zm), zoom, 16) + temp[1] = zm + call iishdr (command, 3, ZOOM, x, 0, 0, 0) + call iisio (temp, 3 * SZB_CHAR) + + # now we have to scroll to the desired location (in GKI). + # If zoom is zero, don't do anything: this will leave the + # various images panned to some previously set place, but + # that is what is wanted when doing split screen and we pan + # some of the images. + + if (zm != 0) { + do i = 1, total + call amovs (data[i * 3 - 1 ], scroll[i*2-1], 2) + scroll[total*2+1] = IDS_EOD + call iisscroll(short(IDS_WRITE), frames, short(total*2+1), scroll) + } +end diff --git a/pkg/images/tv/iis/iism70/mkpkg b/pkg/images/tv/iis/iism70/mkpkg new file mode 100644 index 00000000..9944d732 --- /dev/null +++ b/pkg/images/tv/iis/iism70/mkpkg @@ -0,0 +1,58 @@ +# Makelib file for the image display interface. An image display device is +# accessed by high level code via the GKI interface. + +$checkout libpkg.a ../ +$update libpkg.a +$checkin libpkg.a ../ +$exit + +libpkg.a: + idsexpand.x <gki.h> ../lib/ids.h iis.h + iisbutton.x <mach.h> iis.h ../lib/ids.h iis.com + iiscls.x <mach.h> iis.h iis.com <knet.h> + iiscursor.x <mach.h> iis.h ../lib/ids.h iis.com + iishdr.x <mach.h> iis.h iis.com + iishisto.x <mach.h> iis.h ../lib/ids.h iis.com + iisifm.x <mach.h> iis.h ../lib/ids.h iis.com + iisio.x <mach.h> iis.h iis.com <knet.h> + iislut.x <mach.h> iis.h ../lib/ids.h iis.com + iismatch.x <mach.h> iis.h ../lib/ids.h ../lib/ids.com + iisminmax.x <mach.h> iis.h ../lib/ids.h iis.com + iisoffset.x <mach.h> iis.h ../lib/ids.h iis.com + iisofm.x <mach.h> iis.h ../lib/ids.h iis.com + iisopn.x <mach.h> iis.h iis.com <knet.h> + iispack.x ../lib/ids.h + iispio.x <mach.h> iis.h <knet.h> iis.com + iisrange.x <mach.h> iis.h ../lib/ids.h iis.com + iisrd.x <mach.h> iis.h iis.com + iisscroll.x <gki.h> <mach.h> iis.h ../lib/ids.h iis.com + iissplit.x <mach.h> iis.h ../lib/ids.h iis.com + iistball.x <mach.h> iis.h ../lib/ids.h iis.com + iiswr.x <mach.h> iis.h iis.com + iiswt.x <mach.h> iis.h iis.com <knet.h> + iiszoom.x <mach.h> iis.h ../lib/ids.h iis.com + zardim.x iis.h + zawrim.x + zawtim.x <mach.h> iis.h iis.com + zclear.x <mach.h> ../lib/ids.h iis.h + zclsim.x + zcontrol.x ../lib/ids.h iis.h + zcursor_read.x <gki.h> <mach.h> iis.h ../lib/ids.h iis.com + zcursor_set.x <gki.h> <mach.h> iis.h ../lib/ids.h iis.com + zdisplay_g.x <mach.h> iis.h ../lib/ids.h + zdisplay_i.x <mach.h> iis.h ../lib/ids.h ../lib/ids.com iis.com + zinit.x <mach.h> iis.h ../lib/ids.h ../lib/ids.com iis.com + zopnim.x + zreset.x <gki.h> <mach.h> ../lib/ids.h iis.h iis.com + zrestore.x <mach.h> ../lib/ids.h iis.h + zsave.x <mach.h> ../lib/ids.h iis.h + zseek.x <fset.h> <mach.h> ../lib/ids.h iis.h + + zsetup.x <fset.h> <mach.h> ../lib/ids.h iis.h ../lib/ids.com\ + iis.com + zsnap.x <fset.h> <mach.h> iis.h ../lib/ids.h zsnap.com iis.com\ + ../lib/ids.com + zsnapinit.x <fset.h> <mach.h> iis.h ../lib/ids.h zsnap.com iis.com\ + ../lib/ids.com + zsttim.x <knet.h> + ; diff --git a/pkg/images/tv/iis/iism70/zardim.x b/pkg/images/tv/iis/iism70/zardim.x new file mode 100644 index 00000000..e6811840 --- /dev/null +++ b/pkg/images/tv/iis/iism70/zardim.x @@ -0,0 +1,16 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "iis.h" + +# ZARDIM -- Read data from a binary file display device. + +procedure zardim (chan, buf, nbytes, offset) + +int chan[ARB] +short buf[ARB] +int nbytes +long offset + +begin + call iisrd (chan, buf, nbytes, offset) +end diff --git a/pkg/images/tv/iis/iism70/zawrim.x b/pkg/images/tv/iis/iism70/zawrim.x new file mode 100644 index 00000000..7e5fa266 --- /dev/null +++ b/pkg/images/tv/iis/iism70/zawrim.x @@ -0,0 +1,14 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +# ZAWRIM -- Write data to a binary file display device. + +procedure zawrim (chan, buf, nbytes, offset) + +int chan[ARB] +short buf[ARB] +int nbytes +long offset + +begin + call iiswr (chan, buf, nbytes, offset) +end diff --git a/pkg/images/tv/iis/iism70/zawtim.x b/pkg/images/tv/iis/iism70/zawtim.x new file mode 100644 index 00000000..ef857bdd --- /dev/null +++ b/pkg/images/tv/iis/iism70/zawtim.x @@ -0,0 +1,16 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "iis.h" + +# ZAWTIM -- Wait for an image display frame which is addressable as +# a binary file. + +procedure zawtim (chan, nbytes) + +int chan[ARB], nbytes +include "iis.com" + +begin + call iiswt (chan, nbytes) +end diff --git a/pkg/images/tv/iis/iism70/zclear.x b/pkg/images/tv/iis/iism70/zclear.x new file mode 100644 index 00000000..a03d429c --- /dev/null +++ b/pkg/images/tv/iis/iism70/zclear.x @@ -0,0 +1,33 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "../lib/ids.h" +include "iis.h" + +# ZCLEAR -- Erase IIS frame. + +procedure zclear (frame, bitplane, flag) + +short frame[ARB] # frame array +short bitplane[ARB] # bitplane array +bool flag # true if image plane + +int z, t +short erase +int and(), andi() +short iispack() + +begin + if (flag) { + z = iispack (frame) + z = and (z, ALLCHAN) + } else + z = GRCHAN + + t = iispack (bitplane) + erase = andi (ERASE, 177777B) + + call iishdr (IWRITE+BYPASSIFM+BLOCKXFER, 1, FEEDBACK, + ADVXONTC, ADVYONXOV, z, t) + call iisio (erase, SZB_CHAR) +end diff --git a/pkg/images/tv/iis/iism70/zclsim.x b/pkg/images/tv/iis/iism70/zclsim.x new file mode 100644 index 00000000..a2bd2029 --- /dev/null +++ b/pkg/images/tv/iis/iism70/zclsim.x @@ -0,0 +1,13 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +# ZCLSIM -- Close an image display frame which is addressable as +# a binary file. + +procedure zclsim (chan, status) + +int chan[ARB] +int status + +begin + call iiscls (chan, status) +end diff --git a/pkg/images/tv/iis/iism70/zcontrol.x b/pkg/images/tv/iis/iism70/zcontrol.x new file mode 100644 index 00000000..56d8caeb --- /dev/null +++ b/pkg/images/tv/iis/iism70/zcontrol.x @@ -0,0 +1,116 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../lib/ids.h" +include "iis.h" + +# ZCONTROL -- call the device dependent control routines + +procedure zcontrol(device, rw, frame, color, offset, n, data) + +short device # which device/register to control +short rw # write/read/wait,read +short frame[ARB] # array of image frames +short color[ARB] # array of color +short offset # generalized offset or datum +short n # count of items in data array +short data[ARB] # data array + +begin + switch(device) { + case IDS_FRAME_LUT: + call iislut(rw, frame, color, offset, n, data) + + case IDS_GR_MAP: + # for now, nothing + + case IDS_INPUT_LUT: + call iisifm(rw, offset, n, data) + + case IDS_OUTPUT_LUT: + call iisofm(rw, color, offset, n, data) + + case IDS_SPLIT: + call iissplit(rw, n, data) + + case IDS_SCROLL: + call iisscroll(rw, frame, n, data) + + case IDS_ZOOM: + call iiszoom(rw, frame, n, data) + + case IDS_OUT_OFFSET: + call iisoffset(rw, color, n, data) + + case IDS_MIN: + call iismin(rw, color, n, data) + + case IDS_MAX: + call iismax(rw, color, n, data) + + case IDS_RANGE: + call iisrange(rw, color, n, data) + + case IDS_HISTOGRAM: + call iishisto(rw, color, offset, n, data) + + case IDS_ALU_FCN: + # for now, nothing + + case IDS_FEEDBACK: + # for now, nothing + + case IDS_SLAVE: + # for now, nothing + + case IDS_CURSOR: + call iiscursor(rw, offset, n, data) + + case IDS_TBALL: + call iistball(rw, data) + + case IDS_DIGITIZER: + # for now, nothing + + case IDS_BLINK: + # for now, nothing + + case IDS_SNAP: + call zsnap_init(data[1]) + + case IDS_MATCH: + call iismatch (rw, frame, color, n, data) + } +end + + +# MAPCOLOR - modify the color array to map rgb for iis + +int procedure mapcolor(color) + +short color[ARB] # input data + +int i +int val, result +int or() + +begin + result = 0 + for ( i = 1; color[i] != IDS_EOD ; i = i + 1 ) { + val = color[i] + switch (val) { + case IDS_RED: + val = RED + + case IDS_GREEN: + val = GREEN + + case IDS_BLUE: + val = BLUE + + default: + val = 2**(val-1) + } + result = or (result, val) + } + return (result) +end diff --git a/pkg/images/tv/iis/iism70/zcursor_read.x b/pkg/images/tv/iis/iism70/zcursor_read.x new file mode 100644 index 00000000..6de5bc8e --- /dev/null +++ b/pkg/images/tv/iis/iism70/zcursor_read.x @@ -0,0 +1,96 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <gki.h> +include "iis.h" +include "../lib/ids.h" + +# ZCURSOR_READ -- Read cursor from display. This assumes that the cursor +# is centered at (31,31) + +procedure zcursor_read (cnum, xcur, ycur, key) + +int cnum # cursor number +int xcur, ycur # cursor position...GKI coordinates +int key # key pressed + +short cursor[2] # local storage +real x,y +int frame +real zm +int mod(), and() +define exit_ 10 + +include "iis.com" + +begin + # Computations must be done in floating point when zoomed + # or values are off by a pixel. Also, want fractional + # pixel returned values in the zoomed case. + + call iishdr(IREAD, 2, COMMAND+CURSOR, 1+ADVXONTC, 0,0,0) + call iisio (cursor, 2 * SZB_CHAR) + + # which frame is the cursor relative to? We assume that cnum + # mod IDS_CSET refers to the image plane (graphics fits in + # here as an image plane for iism70), and cnum / IDS_CSET + # sets which cursor. + # If cursor is #0, then take lowest numbered frame that is + # being displayed. + # Return frame number as the "key". + + if (cnum == 0) { + frame = i_frame_on + if ((frame == ERR) || (frame < 1) ) { + key = ERR + return + } + } else if (cnum != IDS_CRAW) { + frame = mod(cnum-1, IDS_CSET) + 1 + } else { + zm = 1. + frame = 0 # return unusual frame num. if raw read + } + + # deal with cursor offset--hardware fault sometimes adds extra + # bit, so chop it off with and(). + x = mod (and (int(cursor[1]), 777B)+ 31, 512) + y = mod (and (int(cursor[2]), 777B)+ 31, 512) + + if (cnum == IDS_CRAW) + goto exit_ + + # x,y now in device coordinates for screen but not world. + # next, we determine number of pixels from screen center. + + zm = zoom[frame] + x = x/zm - IIS_XCEN./zm + y = y/zm - IIS_YCEN_INV./zm + + # Now add in scroll offsets, which are to screen center. + x = x + xscroll[frame] + + # Note that the Y one is inverted + y = y + (IIS_YDIM-1) - yscroll[frame] + + if (x < 0) + x = x + IIS_XDIM + else if (x > IIS_XDIM) + x = x - IIS_XDIM + + if (y < 0) + y = y + IIS_YDIM + else if (y > IIS_YDIM) + y = y - IIS_YDIM +exit_ + # invert y for user + y = (IIS_YDIM -1) - y + + # The Y inversion really complicates things... + y = y + 1.0 - (1.0/zm) + + # convert to GKI + xcur = x * MCXSCALE + ycur = y * MCYSCALE + key = frame +end diff --git a/pkg/images/tv/iis/iism70/zcursor_set.x b/pkg/images/tv/iis/iism70/zcursor_set.x new file mode 100644 index 00000000..50b1d446 --- /dev/null +++ b/pkg/images/tv/iis/iism70/zcursor_set.x @@ -0,0 +1,100 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <gki.h> +include "../lib/ids.h" +include "iis.h" + +# ZCURSOR_SET -- Write cursor to display. This code assumes the standard +# cursor which is centered on (31,31). + +procedure zcursor_set (cnum, xcur, ycur) + +int cnum # cursor number +int xcur, ycur # GKI x,y cursor position + +short cursor[2] # local storage +real x,y,zm +int xedge +int yedge, frame +int mod() +define output 10 + +include "iis.com" + +begin + # which frame does cursor refer to? ( see zcursor_read() for + # more information. ) + + if (cnum == IDS_CRAW) { + x = real(xcur)/MCXSCALE + y = real(ycur)/MCYSCALE + zm = 1 + xedge = 0 + yedge = 0 + goto output + } + + if (cnum == 0) { + frame = i_frame_on + if ((frame == ERR) || (frame < 1)) + return # WHAT SHOULD WE DO? + } else + frame = mod( cnum-1, IDS_CSET) + 1 + zm = zoom[frame] + + # Find the left/upper edge of the display + # xedge is real as we can't drop the fraction of IIS_XCEN/zm + # (This was true when XCEN was 255; now is 256 so can use int + # since 256 is a multiple of all possible values of zm.) + + xedge = xscroll[frame] - IIS_XCEN/zm + if (xedge < 0) + xedge = xedge + IIS_XDIM + yedge = ( (IIS_YDIM-1) - yscroll[frame]) - int(IIS_YCEN_INV/zm) + if (yedge < 0) + yedge = yedge + IIS_YDIM + + # xcur, ycur are in gki. Check if value too big...this will + # happen if NDC = 1.0, for instance which should be acceptable + # but will be "out of range". + + x = real(xcur)/MCXSCALE + if ( x > (IIS_XDIM - 1.0/zm) ) + x = IIS_XDIM - 1.0/zm + y = real(ycur)/MCYSCALE + if ( y > (IIS_YDIM - 1.0/zm) ) + y = IIS_YDIM - 1.0/zm + + # Invert y value to get device orientation; account for + # fractional pixels + +output + y = (IIS_YDIM - 1.0/zm) - y + + # Account for the mod 512 nature of the display + + if (x < xedge) + x = x + IIS_XDIM + if (y < yedge) + y = y + IIS_YDIM + + # Are we still on screen ? + + if ((x >= (xedge + IIS_XDIM/zm)) || (y >= (yedge + IIS_YDIM/zm)) ) { + call eprintf("cursor set off screen -- ignored\n") + return + } + + # Calculate cursor positioning coordinates. + + cursor[1] = int ((x-real(xedge)) * zm ) - 31 + if ( cursor[1] < 0 ) + cursor[1] = cursor[1] + IIS_XDIM + cursor[2] = int ((y-real(yedge)) * zm ) - 31 + if ( cursor[2] < 0 ) + cursor[2] = cursor[2] + IIS_YDIM + + call iishdr (IWRITE+VRETRACE, 2, COMMAND+CURSOR, 1+ADVXONTC, 0,0,0) + call iisio (cursor, 2 * SZB_CHAR) +end diff --git a/pkg/images/tv/iis/iism70/zdisplay_g.x b/pkg/images/tv/iis/iism70/zdisplay_g.x new file mode 100644 index 00000000..21cf9e09 --- /dev/null +++ b/pkg/images/tv/iis/iism70/zdisplay_g.x @@ -0,0 +1,91 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "../lib/ids.h" +include "iis.h" + +define INSERT 100000B + +# ZDISPLAY_G -- Display the referenced graphics bitplanes in the given color(s) + +procedure zdisplay_g (sw, bitpl, color, quad ) + +short sw # on or off +short bitpl[ARB] # bitpl list +short color[ARB] # color list +short quad[ARB] # quadrants to activate + +short gram[LEN_GRAM] +bool off +int i, lbound, val +short mask[7] +short fill +# red a bit weak so have contrast with cursor +#colors of graph: blue grn red yellow rd-bl gn-bl white +data mask /37B, 1740B, 74000B, 77740B, 74037B, 1777B, 77777B/ + +begin + if ( sw == IDS_OFF ) + off = true + else { + off = false + } + + # ignore bitpl argument since only one set of them and "color" + # fully specifies them. + # ignore quad for now + # much manipulation of color graphics ram table required!! + # strictly speaking, when we turn a plane off, we ought to be + # sure that any plane which is on, and "beneath", is turned on; + # this is a lot of trouble, so for starters, we don't. + # first find out what is on + + call iishdr(IREAD+VRETRACE, LEN_GRAM, GRAPHICS, ADVXONTC, 0, 0, 0) + call iisio (gram, LEN_GRAM * SZB_CHAR) + + # Check for red graphics plane for cursor + + if ( gram[LEN_GRAM/2+1] != 176000B ) + call amovks ( short(176000B), gram[LEN_GRAM/2+1], LEN_GRAM/2) + + for ( i = 1 ; color[i] != IDS_EOD ; i = i + 1 ) { + # Bit plane 8 reserved for cursor + if ( color[i] > 7 ) + next + # map IDS colors to IIS bit planes -- one-based. + switch (color[i]) { + case IDS_RED: + val = RD + case IDS_GREEN: + val = GR + case IDS_BLUE: + val = BLU + default: + val = color[i] + } + lbound = 2 ** (val - 1) + if ( off ) + call aclrs ( gram[lbound+1], lbound) + else + call amovks ( short(INSERT+mask[val]), gram[lbound+1], lbound) + } + gram[1] = 0 + + # If a bit plane is off, reset it with next "lower" one, thus + # uncovering any planes masked by the one turned off. + + if (off) { + fill = 0 + do i = 2, LEN_GRAM/2 { + if (gram[i] == 0 ) + gram[i] = fill + else + fill = gram[i] + } + } + + # Write out the data + + call iishdr(IWRITE+VRETRACE, LEN_GRAM, GRAPHICS, ADVXONTC, 0, 0, 0) + call iisio (gram, LEN_GRAM * SZB_CHAR) +end diff --git a/pkg/images/tv/iis/iism70/zdisplay_i.x b/pkg/images/tv/iis/iism70/zdisplay_i.x new file mode 100644 index 00000000..e08db8c3 --- /dev/null +++ b/pkg/images/tv/iis/iism70/zdisplay_i.x @@ -0,0 +1,124 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "../lib/ids.h" +include "iis.h" + +# ZDISPLAY_I -- Display the referenced image planes in the given color(s) +# and in the given quadrants of the screen. + +procedure zdisplay_i (sw, frames, color, quad) + +short sw # on or off +short frames[ARB] # frame list +short color[ARB] # color list +short quad[ARB] # quadrant list + + +bool off +short channels +short select[LEN_SELECT] +int q,c,index, temp +int mq # mapped quadrant +int mapquad() +short iispack() +int and(), or(), xor() + +include "iis.com" +include "../lib/ids.com" # for i_maxframes! only + +begin + if ( sw == IDS_ON ) { + off = false + } else + off = true + + # first find out what is on + call iishdr(IREAD+VRETRACE, LEN_SELECT, COMMAND+LUT, ADVXONTC, 0,0,0) + call iisio (select, LEN_SELECT * SZB_CHAR) + + # then add in/remove frames + channels = iispack(frames) + + for ( q = 1 ; quad[q] != IDS_EOD ; q = q + 1 ) { + mq = mapquad(quad[q]) + if ( ! off ) { + for ( c =1 ; color[c] != IDS_EOD ; c = c + 1 ) { + switch ( color[c] ) { + case IDS_RED: + index = mq + 8 + + case IDS_GREEN: + index = mq + 4 + + case IDS_BLUE: + index = mq + } + select[index] = or ( int(channels), int(select[index]) ) + } + } else { + for ( c =1 ; color[c] != IDS_EOD ; c = c + 1 ) { + switch ( color[c] ) { + case IDS_RED: + index = mq + 8 + + case IDS_GREEN: + index = mq + 4 + + case IDS_BLUE: + index = mq + } + select[index] = and ( xor ( 177777B, int(channels)), + int(select[index])) + } + } + } + + # Record which frame is being displayed for cursor readback. + temp = 0 + do q = 1, LEN_SELECT + temp = or (temp, int(select[q])) + + if ( temp == 0) + i_frame_on = ERR + else { + do q = 1, i_maxframes { + if (and (temp, 2**(q-1)) != 0) { + i_frame_on = q + break + } + } + } + call iishdr(IWRITE+VRETRACE, LEN_SELECT, COMMAND+LUT, ADVXONTC, 0,0,0) + call iisio (select, LEN_SELECT * SZB_CHAR) +end + + +# MAPQUAD -- map user quadrant to device ... returns ONE-based quadrant +# if prefer ZERO-based, add one to "index" computation above. + +int procedure mapquad (quadrant) + +short quadrant + +int mq + +begin + switch ( quadrant ) { + case 1: + mq = 2 + + case 2: + mq = 1 + + case 3: + mq = 3 + + case 4: + mq = 4 + + default: + mq = 1 # should never happen + } + return (mq) +end diff --git a/pkg/images/tv/iis/iism70/zinit.x b/pkg/images/tv/iis/iism70/zinit.x new file mode 100644 index 00000000..e03fd57c --- /dev/null +++ b/pkg/images/tv/iis/iism70/zinit.x @@ -0,0 +1,45 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "../lib/ids.h" +include "iis.h" + +# ZINIT -- initialize for IIS operation +# in general case, would use nfr and ngr to determine maximum file size +# which would encompass all the images and graphics planes and all the +# devices too. Then, file mapped i/o could move most of the device indep. +# code to the reading and writing routines. +# not done for IIS + +procedure zinit (nfr, ngr, filesize) + +short nfr # maximum number of image frames +short ngr # maximum number of graphics bit planes +long filesize # returned value + +short pl[IDS_MAXIMPL+2] +short zm[4] + +include "../lib/ids.com" +include "iis.com" + +begin + i_snap = false + # we have no place to store all the zoom and scroll information. + # so we initialize to zoom = 1 and scroll = center for all planes + pl[1] = IDS_EOD + call ids_expand(pl, i_maxframes, true) + zm[1] = 1 + zm[2] = IIS_XCEN * MCXSCALE + zm[3] = IIS_YCEN * MCYSCALE + zm[4] = IDS_EOD + call iiszoom(short(IDS_WRITE), pl, short(4), zm) + call iisscroll(short(IDS_WRITE), pl, short(3), zm[2]) + + # We also need to set the i_frame_on variable (iis.com), which + # we do with a "trick": We call zdisplay_i with quad == EOD; + # this is a "nop" for the display code, but will set the variable. + + call zdisplay_i (short(IDS_ON), short(IDS_EOD), short(IDS_EOD), + short(IDS_EOD)) +end diff --git a/pkg/images/tv/iis/iism70/zopnim.x b/pkg/images/tv/iis/iism70/zopnim.x new file mode 100644 index 00000000..25df2f21 --- /dev/null +++ b/pkg/images/tv/iis/iism70/zopnim.x @@ -0,0 +1,17 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +# ZOPNIM -- Open an image display frame which is addressable as +# a binary file. + +procedure zopnim (devinfo, mode, chan) + +char devinfo[ARB] # packed devinfo string +int mode # access mode +int chan + +int iischan[2] # Kludge + +begin + call iisopn (devinfo, mode, iischan) + chan = iischan[1] +end diff --git a/pkg/images/tv/iis/iism70/zreset.x b/pkg/images/tv/iis/iism70/zreset.x new file mode 100644 index 00000000..3d067d04 --- /dev/null +++ b/pkg/images/tv/iis/iism70/zreset.x @@ -0,0 +1,164 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <gki.h> +include "../lib/ids.h" +include "iis.h" + +# cfactor is conversion from integer to NDC coordinates (max 32767) for cursor +# see iiscursor.x +# The "hardness" notion is now somewhat obsolete...a range of reset values +# would be better, especially if better named. + +define CFACTOR 528 + +# ZRESET -- reset IIS + +procedure zreset (hardness) + +short hardness # soft, medium, hard + +short data[LEN_IFM] +short frames[IDS_MAXIMPL+1] +short colors[IDS_MAXGCOLOR+1] +short quad[5] +int i,j + +include "iis.com" + +begin + if ( hardness == IDS_R_SNAPDONE ) { + call zsnap_done + return + } + + # mark all frames + do i = 1,IDS_MAXIMPL + frames[i] = i + frames[IDS_MAXIMPL+1] = IDS_EOD + # mark all colors + do i = 1, IDS_MAXGCOLOR + colors[i] = i + colors[IDS_MAXGCOLOR+1] = IDS_EOD + # all quadrants + do i = 1,4 + quad[i] = i + quad[5] = IDS_EOD + + if ( hardness == IDS_R_SOFT) { + # all coordinates are NDC ( 0 - 32767 ) + # Reseting the "soft" parameters: scroll, constant offsets, + # split point, alu, zoom; turn cursor and tball on. + + # constants + call aclrs (data,3) + call iisoffset(short(IDS_WRITE), colors, short(3), data) + + # range + data[1] = 1 + call iisrange (short(IDS_WRITE), colors, short(1), data) + + # split point + call aclrs ( data, 2) + call iissplit(short(IDS_WRITE), short(2), data) + + # alu + data[1] = 0 + call iishdr(IWRITE, 1, ALU+COMMAND, 0, 0, 0, 0) + call iisio (data, 1 * SZB_CHAR) + + # graphics status register + data[1] = 0 + call iishdr(IWRITE, 1, GRAPHICS+COMMAND, 0, 0, 0, 0) + call iisio (data, 1 * SZB_CHAR) + + # zoom + data[1] = 1 + data[2] = IIS_XCEN * MCXSCALE # gki mid point + data[3] = IIS_YCEN * MCYSCALE + data[4] = IDS_EOD + call iiszoom(short(IDS_WRITE), frames, short(4), data) + + # scroll -- screen center to be centered + # zoom does affect scroll if zoom not power==1 + # so to be safe, do scroll after zoom. + data[1] = IIS_XCEN * MCXSCALE + data[2] = IIS_YCEN * MCYSCALE + data[3] = IDS_EOD + call iisscroll(short(IDS_WRITE), frames, short(3), data) + + # cursor and tball; no blink for cursor + data[1] = IDS_ON + call iiscursor(short(IDS_WRITE), short(1), short(1), data) + call iistball (short(IDS_WRITE), data) + data[1] = IDS_CBLINK + data[2] = IDS_CSTEADY + call iiscursor(short(IDS_WRITE), short(1), short(1), data) + + # standard cursor shape + data[1] = IDS_CSHAPE + j = 2 + # don't use last line/column so have a real center + for ( i = 0 ; i <= 62 ; i = i + 1 ) { + # make the puka in the middle + if ( (i == 30) || (i == 31) || (i == 32) ) + next + # fill in the lines + data[j] = 31 * CFACTOR + data[j+1] = i * CFACTOR + j = j + 2 + data[j] = i * CFACTOR + data[j+1] = 31 * CFACTOR + j = j + 2 + } + data[j] = IDS_EOD + call iiscursor ( short(IDS_WRITE), short(1), short(j), data) + + return + } + + if ( hardness == IDS_R_MEDIUM) { + # reset all tables to linear--ofm, luts, ifm + # ofm (0,0) to (0.25,1.0) to (1.0,1.0) + data[1] = 0 + data[2] = 0 + data[3] = 0.25 * GKI_MAXNDC + data[4] = GKI_MAXNDC + data[5] = GKI_MAXNDC + data[6] = GKI_MAXNDC + call iisofm(short(IDS_WRITE), colors, short(1), short(6), data) + + # luts + data[1] = 0 + data[2] = 0 + data[3] = GKI_MAXNDC + data[4] = GKI_MAXNDC + call iislut(short(IDS_WRITE), frames, colors, short(1), + short(4), data) + + # ifm (0,0) to (1/32, 1.0) to (1.,1.) + # ifm is length 8192, but output is only 255. So map linearly for + # first 256, then flat. Other possibility is ifm[i] = i-1 ( for + # i = 1,8192) which relies on hardware dropping high bits. + + data[1] = 0 + data[2] = 0 + data[3] = (1./32.) * GKI_MAXNDC + data[4] = GKI_MAXNDC + data[5] = GKI_MAXNDC + data[6] = GKI_MAXNDC + call iisifm(short(IDS_WRITE), short(1), short(6), data) + + return + } + + if (hardness == IDS_R_HARD) { + # clear all image/graph planes, and set channel selects to + # mono + call zclear(frames, frames, true) + call zclear(frames, frames, false) + # reset all to no display + call zdisplay_i(short(IDS_OFF), frames, colors, quad) + call zdisplay_g(short(IDS_OFF), frames, colors, quad) + } +end diff --git a/pkg/images/tv/iis/iism70/zrestore.x b/pkg/images/tv/iis/iism70/zrestore.x new file mode 100644 index 00000000..ed478a20 --- /dev/null +++ b/pkg/images/tv/iis/iism70/zrestore.x @@ -0,0 +1,30 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "../lib/ids.h" +include "iis.h" + +# restore device, image, graphics data + +procedure zdev_restore(fd) + +int fd # file descriptor to read from + +begin +end + +procedure zim_restore(fd, frame) + +int fd +short frame[ARB] # frame numbers to restore + +begin +end + +procedure zgr_restore(fd, plane) + +int fd +short plane[ARB] + +begin +end diff --git a/pkg/images/tv/iis/iism70/zsave.x b/pkg/images/tv/iis/iism70/zsave.x new file mode 100644 index 00000000..666f1b1f --- /dev/null +++ b/pkg/images/tv/iis/iism70/zsave.x @@ -0,0 +1,30 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include "../lib/ids.h" +include "iis.h" + +# save device, image, graphics data + +procedure zdev_save(fd) + +int fd # file descriptor to write to + +begin +end + +procedure zim_save(fd, frame) + +int fd +short frame[ARB] # frame numbers to save + +begin +end + +procedure zgr_save(fd, plane) + +int fd +short plane[ARB] + +begin +end diff --git a/pkg/images/tv/iis/iism70/zseek.x b/pkg/images/tv/iis/iism70/zseek.x new file mode 100644 index 00000000..6f3fed25 --- /dev/null +++ b/pkg/images/tv/iis/iism70/zseek.x @@ -0,0 +1,21 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <fset.h> +include "../lib/ids.h" +include "iis.h" + +# ZSEEK -- Seek for an image frame + +procedure zseek (fd, x, y) + +int fd # file to write +int x, y # device coordinates + +long offset + +begin + offset = max (1, 1 + (x + y * IIS_XDIM) * SZ_SHORT) + + call seek (fd, offset) +end diff --git a/pkg/images/tv/iis/iism70/zsetup.x b/pkg/images/tv/iis/iism70/zsetup.x new file mode 100644 index 00000000..0803ac3a --- /dev/null +++ b/pkg/images/tv/iis/iism70/zsetup.x @@ -0,0 +1,34 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <fset.h> +include "../lib/ids.h" +include "iis.h" + +# ZSETUP -- Setup up common block information for read/write + +procedure zsetup (frame, bitpl, flag) + +short frame[ARB] # frame information +short bitpl[ARB] # bitplane information +bool flag # true if image, false if graphics + +short iispack() +int mapcolor() + +include "iis.com" +include "../lib/ids.com" + +begin + # If don't flush, then last line of "previous" frame + # may get steered to wrong image plane + call flush (i_out) + call fseti (i_out, F_CANCEL, OK) + if ( flag ) { + iframe = iispack ( frame ) + iplane = iispack ( bitpl ) + } else { + iframe = GRCHAN + iplane = mapcolor( bitpl ) + } +end diff --git a/pkg/images/tv/iis/iism70/zsnap.com b/pkg/images/tv/iis/iism70/zsnap.com new file mode 100644 index 00000000..8dd6796c --- /dev/null +++ b/pkg/images/tv/iis/iism70/zsnap.com @@ -0,0 +1,26 @@ +# snap common block +int sn_fd # device file descriptor +int sn_frame, sn_bitpl # save current iframe, iplane +int zbufsize # fio buffer size--save here +pointer lutp[3,LEN_IISFRAMES] # look up table storage +pointer ofmp[3] # rgb ofm tables +pointer grp[3] # graphics tables +pointer result[3] # rgb results +pointer answer # final answer +pointer input # input data +pointer zs # zoom/scrolled data; scratch +pointer grbit_on # graphics bit on +bool gr_in_use # graphics RAM not all zeroes +bool on[LEN_IISFRAMES] # if frames on at all +bool multi_frame # snap using >1 frame +short range[3] # range and offset for rgb +short offset[3] +short left[3,2,LEN_IISFRAMES] # left boundary of line +short right[3,2,LEN_IISFRAMES] # right boundary of line +short ysplit # split point for y +short prev_y # previous line read +short sn_start, sn_end # color range to snap + +common / zsnap / sn_fd, sn_frame, sn_bitpl, zbufsize, lutp, ofmp, grp, + result, answer, input, zs, grbit_on, gr_in_use, on, multi_frame, + range, offset, left, right, ysplit, prev_y, sn_start, sn_end diff --git a/pkg/images/tv/iis/iism70/zsnap.x b/pkg/images/tv/iis/iism70/zsnap.x new file mode 100644 index 00000000..c0f9b230 --- /dev/null +++ b/pkg/images/tv/iis/iism70/zsnap.x @@ -0,0 +1,239 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <fset.h> +include "iis.h" +include "../lib/ids.h" + +# DO_SNAP -- Return a line of the active image display, as seen +# by the viewer. + +procedure do_snap (buf, nchar, xpos, ypos) + +short buf[ARB] # buffer to read into +int nchar # how many to read +int xpos, ypos # and from where + +int y, yindex, xs, xe +int line, previous +int i,j +int yedge +int zm, count +bool first + +include "../lib/ids.com" +include "iis.com" +include "zsnap.com" + +begin + # Check if read is for one line only + + if (nchar > IIS_XDIM) { + call eprintf("ZSNAP -- too many pixels (%d) requested.\n") + call pargi (nchar) + call aclrs (buf, nchar) + return + } + + # Determine x and y coordinates on screen. + + y = IIS_YDIM - 1 - ypos + xs = xpos + xe = xs + nchar - 1 + count = nchar + + # See if we are dealing with (a part of only) one line + + if (xe >= IIS_XDIM) { + call eprintf("ZSNAP -- line overlap error (xend is %d).\n") + call pargi (xe) + call aclrs (buf, nchar) + return + } + + # Determine whether above or below split point. + + if (y < ysplit) + yindex = 1 + else + yindex = 2 + + # Clear accumulators + + do j = sn_start, sn_end + call aclrs (Mems[result[j]], IIS_XDIM) + + # Fetch and massage data for each active frame + + first = true + previous = -1 # a bit of safety if no frames on + do i = 1, i_maxframes { + if (on[i]) { + # If frame not active in any color for this half of screen, + # ignore it + if (sn_start != sn_end) { + if ((left[BLU, yindex, i] == -1) && + (left[GR , yindex, i] == -1) && + (left[RD , yindex, i] == -1) ) + next + } else if (left[sn_start, yindex, i] == -1) + next + + zm = zoom[i] + iplane = 377B # all bit planes + iframe = 2**(i-1) + + # y edge of frame (top) [ see zcursor_set for more information] + yedge = IIS_YCEN - yscroll[i] + IIS_YCEN_INV - IIS_YCEN_INV/zm + if (yedge < 0) + yedge = yedge + IIS_YDIM + + # Desired y (screen) coordinate + line = yedge + y/zm + if (line >= IIS_YDIM) + line = line - IIS_YDIM + # If have done this line before, just return the same answer + + if (first) { + if (line == prev_y) { + call amovs (Mems[answer], buf, nchar) + return + } + previous = line + first = false + } + + # Turn line into file position. + line = IIS_YDIM - 1 - line + if (multi_frame) + call fseti (sn_fd, F_CANCEL, OK) + call zseek (sn_fd, xs, line) + call read (sn_fd, Mems[input], count) + call zmassage (zm, xscroll[i], yindex, i, xs, xe) + } + } + + # Apply scaling + + do j = sn_start, sn_end { + # Note...xs, xe are zero-based indices + if ( offset[j] != 0) + call aaddks (Mems[result[j]+xs], offset[j], + Mems[result[j]+xs], count) + if ( range[j] != 1) + call adivks (Mems[result[j]+xs], range[j], + Mems[result[j]+xs], count) + call aluts (Mems[result[j]+xs], Mems[result[j]+xs], count, + Mems[ofmp[j]]) + } + + # Or in the graphics ... use of "select" (asel) depends on design + # decision in zdisplay_g.x + + if (gr_in_use) { + iframe = GRCHAN + iplane = 177B # ignore cursor plane + zm = zoom[GRCHNUM] + + yedge = IIS_YCEN - yscroll[GRCHNUM] + IIS_YCEN_INV - IIS_YCEN_INV/zm + if (yedge < 0) + yedge = yedge + IIS_YDIM + + line = yedge + y/zm + if (line >= IIS_YDIM) + line = line - IIS_YDIM + line = IIS_YDIM - 1 - line + + if (multi_frame) + call fseti (sn_fd, F_CANCEL, OK) + + call zseek (sn_fd, xs, line) + call read (sn_fd, Mems[input], count) + call zmassage (zm, xscroll[GRCHNUM], yindex, GRCHNUM, xs, xe) + + do j = sn_start, sn_end { + call aluts (Mems[input+xs], Mems[zs], count, Mems[grp[j]]) + + # Build boolean which says if have graphics on + call abneks (Mems[zs], short(0), Memi[grbit_on], count) + + # With INSERT on: replace data with graphics. + call asels (Mems[zs], Mems[result[j]+xs], Mems[result[j]+xs], + Memi[grbit_on], count) + } + } + + # The answer is: + + if (sn_start != sn_end) { + call aadds (Mems[result[BLU]], Mems[result[GR]], + Mems[answer], IIS_XDIM) + call aadds (Mems[answer], Mems[result[RD]], Mems[answer], IIS_XDIM) + call adivks (Mems[answer], short(3), Mems[answer], IIS_XDIM) + } else { + # Put in "answer" so repeated lines are in known location + call amovs (Mems[result[sn_start]], Mems[answer], nchar) + } + + # Set the previous line and return the answer + + prev_y = previous + call amovs (Mems[answer], buf, nchar) +end + + +# ZMASSAGE --- do all the boring massaging of the data: zoom, scroll, look +# up tables. + +procedure zmassage (zm, xscr, yi, i, xstart, xend) + +int zm # zoom factor +short xscr # x scroll +int yi # y-index +int i # frame index +int xstart, xend # indices for line start and end + +int lb, count # left bound, count of number of items +int j, x1, x2, itemp +include "zsnap.com" + +begin + if ( (xscr != IIS_XCEN) || (zm != 1)) { + if (xscr == IIS_XCEN) + # Scrolling not needed + call amovs (Mems[input], Mems[zs], IIS_XDIM) + else { + # Scroll the data + lb = xscr - IIS_XCEN + if ( lb < 0 ) + lb = lb + IIS_XDIM + count = IIS_XDIM - lb + call amovs (Mems[input+lb], Mems[zs], count) + call amovs (Mems[input], Mems[zs+count], lb) + } + # Now zoom it + if (zm == 1) + call amovs (Mems[zs], Mems[input], IIS_XDIM) + else + call ids_blockit (Mems[zs+IIS_XCEN-IIS_XCEN/zm], Mems[input], + IIS_XDIM, real(zm)) + } + + if (i == GRCHNUM) + return + + # With the aligned data, perform the lookup. Note that left is + # 0 based, right is (0-based) first excluded value. + + do j = sn_start, sn_end { + if (left[j, yi, i] == -1) + next + itemp = left[j,yi,i] + x1 = max (itemp, xstart) + itemp = right[j,yi,i] + x2 = min (itemp - 1, xend) + call aluts (Mems[input+x1], Mems[zs], x2-x1+1, Mems[lutp[j,i]]) + call aadds (Mems[zs], Mems[result[j]+x1], Mems[result[j]+x1], + x2-x1+1) + } +end diff --git a/pkg/images/tv/iis/iism70/zsnapinit.x b/pkg/images/tv/iis/iism70/zsnapinit.x new file mode 100644 index 00000000..48ed083c --- /dev/null +++ b/pkg/images/tv/iis/iism70/zsnapinit.x @@ -0,0 +1,314 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <fset.h> +include "iis.h" +include "../lib/ids.h" + +define XSPLIT LEN_SELECT+1 +define YSPLIT LEN_SELECT+2 + +# ZSNAP_INIT -- initialize snap data structures. + +procedure zsnap_init(kind) + +short kind + +pointer ptr +short gram[LEN_GRAM] +short select[LEN_SELECT+2] # include split points +short color[4] +short frame[2] +short cds, off, num +short xsplit, x_right + +int i, j, k, temp +int khp, val, frame_count +bool used, mono +int and(), or(), fstati() + +include "zsnap.com" +include "iis.com" +include "../lib/ids.com" + +begin + i_snap = true + sn_frame = iframe + sn_bitpl = iplane + sn_fd = i_out + call flush(sn_fd) + call fseti(sn_fd, F_CANCEL, OK) + prev_y = -1 + + # Determine what snap range to do + if (kind == IDS_SNAP_MONO) + mono= true + else + mono = false + + switch (kind) { + case IDS_SNAP_RGB: + # Note: BLU < RD and covers full color range + sn_start = BLU + sn_end = RD + + case IDS_SNAP_MONO, IDS_SNAP_BLUE: + sn_start = BLU + sn_end = BLU + + case IDS_SNAP_GREEN: + sn_start = GR + sn_end = GR + + case IDS_SNAP_RED: + sn_start = RD + sn_end = RD + } + + # Find out which planes are active -- any quadrant + + call iishdr (IREAD, LEN_SELECT+2, COMMAND+LUT, ADVXONTC, 0, 0, 0) + call iisio (select, (LEN_SELECT+2)*SZB_CHAR) + + # record split point. Adjust x_split so 511 becomes + # 512. This is so the "right" side of a quadrant is given by one + # plus the last used point. + + ysplit = select[YSPLIT] + xsplit = select[XSPLIT] + x_right = xsplit + if (x_right == IIS_XDIM-1) + x_right = IIS_XDIM + + + # For certain split positions, some quadrants don't appear at all. + + if (xsplit == 0) + call nullquad (0, 2, select) + else if (xsplit == IIS_XDIM-1) + call nullquad (1, 3, select) + if (ysplit == 0) + call nullquad (0, 1, select) + else if (ysplit == IIS_YDIM-1) + call nullquad (2, 3, select) + + # Which frames are active, in any quadrant? + + temp = 0 + do i = 1, LEN_SELECT + temp = or (temp, int(select[i])) + do i = 1, i_maxframes { + if ( and (temp, 2**(i-1)) != 0) + on[i] = true + else + on[i] = false + } + + # Find out where each active plane starts and stops. Split points + # are screen coordinates, not picture coordinates. Graphics does + # not split (!). left coord is inclusive, right is one beyond end. + # left/right dimensions: color, above/below_ysplit, image_plane. + # Frame_count counts frames in use. Could be clever and only count + # active frames whose pixels are on the screen (pan/zoom effects). + + frame_count = 0 + do i = 1, i_maxframes { + if ( !on[i] ) + next + else + frame_count = frame_count + 1 + do j = sn_start, sn_end { # implicit BLUE (GREEN RED) + # quadrants for IIS are UL:0, UR:1, LL:2, LR:3 + do k = 0, 3 { + temp = select[(j-1)*4 + k + 1] + used = (and(temp, 2**(i-1)) != 0) + khp = k/2 + 1 + switch (k) { + case 0, 2: + if (used) { + left[j,khp,i] = 0 + right[j,khp,i] = x_right + } else { + left[j,khp,i] = -1 + } + + case 1, 3: + if (used) { + if ( left[j,khp,i] == -1) + left[j,khp,i] = xsplit + right[j,khp,i] = IIS_XDIM + } + } # end switch + } # end k ( quad loop) + } # end j ( color loop) + } # end i ( frame loop) + + # now do range and offset + + cds = IDS_READ + num = 3 + color[1] = IDS_BLUE + color[2] = IDS_GREEN + color[3] = IDS_RED + color[4] = IDS_EOD + call iisrange(cds, color, num, range) + call iisoffset(cds, color, num, offset) + do i = sn_start, sn_end + range[i] = 2**range[i] + + # now allocate memory for all the various tables + + call malloc (input, IIS_XDIM, TY_SHORT) + call malloc (answer, IIS_XDIM, TY_SHORT) + call malloc (zs, IIS_XDIM, TY_SHORT) + # for each color: + do j = sn_start, sn_end { + call malloc (result[j], IIS_XDIM, TY_SHORT) + call malloc (ofmp[j], LEN_OFM, TY_SHORT) + call malloc (grp[j], LEN_GRAM/2, TY_SHORT) + do i = 1, i_maxframes { + if ( on[i] ) + call malloc (lutp[j,i], LEN_LUT, TY_SHORT) + } + } + call malloc (grbit_on, IIS_XDIM, TY_INT) + + # fill these up + + cds = IDS_READ + off = 1 + frame[2] = IDS_EOD + color[2] = IDS_EOD + do j = sn_start, sn_end { + if (j == BLU) + color[1] = IDS_BLUE + else if ( j == GR) + color[1] = IDS_GREEN + else + color[1] = IDS_RED + num = LEN_OFM + call iisofm (cds, color, off, num, Mems[ofmp[j]]) + do i = 1, i_maxframes { + if (on[i]) { + frame[1] = i + num = LEN_LUT + call iislut (cds, frame, color, off, num, Mems[lutp[j,i]]) + } + } + } + + # the graphics planes ... assume insert mode!! + # Note if any graphics mapping ram is in use...if no graphics on, + # snap can run faster. + + call iishdr (IREAD, LEN_GRAM, GRAPHICS, ADVXONTC, 0, 0, 0) + call iisio (gram, LEN_GRAM * SZB_CHAR) + + gr_in_use = false + do j = sn_start, sn_end + call aclrs(Mems[grp[j]], LEN_GRAM/2) + # Leave first one 0; don't mess with cursor plane + do i = 2, LEN_GRAM/2 { + temp = and (77777B, int(gram[i])) + if (temp != 0) + gr_in_use = true + if (! mono) { + do j = sn_start, sn_end + switch (j) { + case RD: + Mems[grp[RD]+i-1] = and (temp,76000B)/32 + case GR: + Mems[grp[GR]+i-1] = and (temp, 1740B) + case BLU: + Mems[grp[BLU]+i-1] = and (temp, 37B)*32 + } + } else { + # All graphics planes + val = or ( and (temp, 76000B)/32, and (temp, 1740B)) + val = or ( and (temp, 37B)*32, val) + Mems[grp[sn_start]+i-1] = val + } + } + + if (gr_in_use) + frame_count = frame_count + 1 + if (frame_count > 1) { + multi_frame = true + # set buffer to size of one line + zbufsize = fstati (sn_fd, F_BUFSIZE) + call fseti (sn_fd, F_BUFSIZE, IIS_XDIM) + } else + multi_frame = false + + # Now adjust look up tables for fact that they do 9 bit 2's complement + # arithmetic! + do j = sn_start, sn_end { + do i = 1, i_maxframes { + if (on[i]) { + ptr = lutp[j,i] + do k = 1, LEN_LUT { + if (Mems[ptr+k-1] > 255 ) + Mems[ptr+k-1] = Mems[ptr+k-1] - 512 + } + } + } + } +end + + +# NULLQUAD -- zero out lut mapping for quadrants that cannot appear on +# screen + +procedure nullquad (q, p, sel) + +int q, p # two quadrants to eliminate, zero based +short sel[ARB] # the mapping array + +int i + +begin + do i = 0,2 { + sel[i*4 + q + 1] = 0 + sel[i*4 + p + 1] = 0 + } +end + + +# ZSNAP_DONE -- reset paramters + +procedure zsnap_done() + +int i,j + +include "iis.com" +include "zsnap.com" +include "../lib/ids.com" + +begin + if ( ! i_snap ) + return + i_snap = false + call fseti(sn_fd, F_CANCEL, OK) + if (multi_frame) { + # restore buffering + call fseti (sn_fd, F_BUFSIZE, zbufsize) + } + iframe = sn_frame + iplane = sn_bitpl + + # release storage + call mfree (grbit_on, TY_INT) + do j = sn_start, sn_end { + call mfree (result[j], TY_SHORT) + call mfree (ofmp[j], TY_SHORT) + call mfree (grp[j], TY_SHORT) + do i = 1, i_maxframes { + if ( on[i] ) + call mfree (lutp[j,i], TY_SHORT) + } + } + + call mfree (zs, TY_SHORT) + call mfree (answer, TY_SHORT) + call mfree (input, TY_SHORT) +end diff --git a/pkg/images/tv/iis/iism70/zsttim.x b/pkg/images/tv/iis/iism70/zsttim.x new file mode 100644 index 00000000..2f441ed7 --- /dev/null +++ b/pkg/images/tv/iis/iism70/zsttim.x @@ -0,0 +1,14 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <knet.h> + +# ZSTTIM -- Return status on binary file display device. + +procedure zsttim (chan, what, lvalue) + +int chan[ARB], what +long lvalue + +begin + call zsttgd (chan, what, lvalue) +end diff --git a/pkg/images/tv/iis/lib/ids.com b/pkg/images/tv/iis/lib/ids.com new file mode 100644 index 00000000..cd6bc086 --- /dev/null +++ b/pkg/images/tv/iis/lib/ids.com @@ -0,0 +1,25 @@ +# IDS common. A common is necessary since there is no graphics descriptor +# in the argument list of the kernel procedures. The data structures +# are designed along the lines of FIO: a small common is used to hold the time +# critical data elements, and an auxiliary dynamically allocated descriptor is +# used for everything else. + +pointer i_kt # kernel image display descriptor +pointer i_tty # graphcap descriptor +int i_in, i_out # input file, output file +int i_xres, i_yres # desired device resolution +long i_frsize # frame size in chars +short i_maxframes, i_maxgraph # max num. of image frames, gr. planes +int i_linemask # current linemask +int i_linewidth # current line width +int i_linecolor # current line color +short i_pt_x, i_pt_y # current plot point, device coords +int i_csize # text character size +int i_font # text font +bool i_snap # true if a snap in progress +bool i_image # frame/bitplane data is for image +char i_device[SZ_IDEVICE] # force output to named device + +common /idscom/ i_kt, i_tty, i_in, i_out, i_xres, i_yres, i_frsize, + i_maxframes, i_maxgraph, i_linemask, i_linewidth, i_linecolor, + i_pt_x, i_pt_y, i_csize, i_font, i_snap, i_image, i_device diff --git a/pkg/images/tv/iis/lib/ids.h b/pkg/images/tv/iis/lib/ids.h new file mode 100644 index 00000000..bbf36392 --- /dev/null +++ b/pkg/images/tv/iis/lib/ids.h @@ -0,0 +1,175 @@ +# IDS definitions. + +define MAX_CHARSIZES 10 # max discreet device char sizes +define SZ_SBUF 1024 # initial string buffer size +define SZ_IDEVICE 31 # maxsize forced device name + +# The IDS state/device descriptor. + +define LEN_IDS 81 + +define IDS_SBUF Memi[$1] # string buffer +define IDS_SZSBUF Memi[$1+1] # size of string buffer +define IDS_NEXTCH Memi[$1+2] # next char pos in string buf +define IDS_NCHARSIZES Memi[$1+3] # number of character sizes +define IDS_POLYLINE Memi[$1+4] # device supports polyline +define IDS_POLYMARKER Memi[$1+5] # device supports polymarker +define IDS_FILLAREA Memi[$1+6] # device supports fillarea +define IDS_CELLARRAY Memi[$1+7] # device supports cell array +define IDS_ZRES Memi[$1+8] # device resolution in Z +define IDS_FILLSTYLE Memi[$1+9] # number of fill styles +define IDS_ROAM Memi[$1+10] # device supports roam +define IDS_CANZM Memi[$1+11] # device supports zoom +define IDS_SELERASE Memi[$1+12] # device has selective erase +define IDS_FRAME Memi[$1+13] # pointer to frames area +define IDS_BITPL Memi[$1+14] # pointer to bitplane area + # extra space +define IDS_FRCOLOR Memi[$1+18] # frame color +define IDS_GRCOLOR Memi[$1+19] # graphics color +define IDS_LCURSOR Memi[$1+20] # last cursor accessed +define IDS_COLOR Memi[$1+21] # last color set +define IDS_TXSIZE Memi[$1+22] # last text size set +define IDS_TXFONT Memi[$1+23] # last text font set +define IDS_TYPE Memi[$1+24] # last line type set +define IDS_WIDTH Memi[$1+25] # last line width set +define IDS_DEVNAME Memi[$1+26] # name of open device +define IDS_CHARHEIGHT Memi[$1+30+$2-1] # character height +define IDS_CHARWIDTH Memi[$1+40+$2-1] # character width +define IDS_CHARSIZE Memr[P2R($1+50+$2-1)] # text sizes permitted +define IDS_PLAP ($1+60) # polyline attributes +define IDS_PMAP ($1+64) # polymarker attributes +define IDS_FAAP ($1+68) # fill area attributes +define IDS_TXAP ($1+71) # default text attributes + +# Substructure definitions. + +define LEN_PL 4 +define PL_STATE Memi[$1] # polyline attributes +define PL_LTYPE Memi[$1+1] +define PL_WIDTH Memi[$1+2] +define PL_COLOR Memi[$1+3] + +define LEN_PM 4 +define PM_STATE Memi[$1] # polymarker attributes +define PM_LTYPE Memi[$1+1] +define PM_WIDTH Memi[$1+2] +define PM_COLOR Memi[$1+3] + +define LEN_FA 3 # fill area attributes +define FA_STATE Memi[$1] +define FA_STYLE Memi[$1+1] +define FA_COLOR Memi[$1+2] + +define LEN_TX 10 # text attributes +define TX_STATE Memi[$1] +define TX_UP Memi[$1+1] +define TX_SIZE Memi[$1+2] +define TX_PATH Memi[$1+3] +define TX_SPACING Memr[P2R($1+4)] +define TX_HJUSTIFY Memi[$1+5] +define TX_VJUSTIFY Memi[$1+6] +define TX_FONT Memi[$1+7] +define TX_QUALITY Memi[$1+8] +define TX_COLOR Memi[$1+9] + +define IDS_EOD (-2) # flag for end of data + +define IDS_RESET 10 # escape 10 +define IDS_R_HARD 0 # hard reset +define IDS_R_MEDIUM 1 # medium +define IDS_R_SOFT 2 +define IDS_R_SNAPDONE 3 # end snap + +define IDS_SET_IP 11 # escape 11 +define IDS_SET_GP 12 # escape 12 +define IDS_DISPLAY_I 13 # escape 13 +define IDS_DISPLAY_G 14 # escape 14 +define IDS_SAVE 15 # escape 15 +define IDS_RESTORE 16 # escape 16 + +# max sizes + +define IDS_MAXIMPL 16 # maximum number of image planes +define IDS_MAXGRPL 16 # maximum number of graphics planes +define IDS_MAXBITPL 16 # maximum bit planes per frame +define IDS_MAXGCOLOR 8 # maximum number of colors (graphics) +define IDS_MAXDATA 8192 # maximum data structure in display + +define IDS_RED 1 +define IDS_GREEN 2 +define IDS_BLUE 3 +define IDS_YELLOW 4 +define IDS_RDBL 5 +define IDS_GRBL 6 +define IDS_WHITE 7 +define IDS_BLACK 8 + +define IDS_QUAD_UR 1 # upper right quad.: split screen mode +define IDS_QUAD_UL 2 +define IDS_QUAD_LL 3 +define IDS_QUAD_LR 4 + +define IDS_CONTROL 17 # escape 17 +define IDS_CTRL_LEN 6 +define IDS_CTRL_REG 1 # what to control +define IDS_CTRL_RW 2 # read/write field in control instr. +define IDS_CTRL_N 3 # count of DATA items +define IDS_CTRL_FRAME 4 # pertinent frame(s) +define IDS_CTRL_COLOR 5 # and color +define IDS_CTRL_OFFSET 6 # generalized "register" +define IDS_CTRL_DATA 7 # data array + +define IDS_WRITE 0 # write command +define IDS_READ 1 # read command +define IDS_READ_WT 2 # wait for action, then read +define IDS_OFF 1 # turn whatever off +define IDS_ON 2 +define IDS_CBLINK 3 # cursor blink +define IDS_CSHAPE 4 # cursor shape + +define IDS_CSTEADY 1 # cursor blink - steady (no blink) +define IDS_CFAST 2 # cursor blink - fast +define IDS_CMEDIUM 3 # cursor blink - medium +define IDS_CSLOW 4 # cursor blink - slow + +define IDS_FRAME_LUT 1 # look-up table for image frame +define IDS_GR_MAP 2 # graphics color map...lookup table per + # se makes little sense for bit plane +define IDS_INPUT_LUT 3 # global input lut +define IDS_OUTPUT_LUT 4 # final lut +define IDS_SPLIT 5 # split screen coordinates +define IDS_SCROLL 6 # scroll coordinates +define IDS_ZOOM 7 # zoom magnification +define IDS_OUT_OFFSET 8 # output bias +define IDS_MIN 9 # data minimum +define IDS_MAX 10 # data maximum +define IDS_RANGE 11 # output range select +define IDS_HISTOGRAM 12 # output data histogram +define IDS_ALU_FCN 13 # arithmetic feedback function +define IDS_FEEDBACK 14 # feedback control +define IDS_SLAVE 15 # auxillary host or slave processor + +define IDS_CURSOR 20 # cursor control - on/off/blink/shape +define IDS_TBALL 21 # trackball control - on/off +define IDS_DIGITIZER 22 # digitizer control - on/off +define IDS_BLINK 23 # for blink request +define IDS_SNAP 24 # snap function +define IDS_MATCH 25 # match lookup tables + +# snap codes ... just reuse color codes from above. +define IDS_SNAP_RED IDS_RED # snap the blue image +define IDS_SNAP_GREEN IDS_GREEN # green +define IDS_SNAP_BLUE IDS_BLUE # blue +define IDS_SNAP_RGB IDS_BLACK # rgb image --- do all three +define IDS_SNAP_MONO IDS_WHITE # do just one + +# cursor parameters + +define IDS_CSET 128 # number of cursors per "group" + +define IDS_CSPECIAL 4097 # special "cursors" + # must be > (IDS_CSET * number of cursor groups) +define IDS_CRAW IDS_CSPECIAL # raw cursor read +define IDS_BUT_RD 4098 # "cursor number" for read buttons cmd +define IDS_BUT_WT 4099 # wait for button press, then read +define IDS_CRAW2 4100 # A second "raw" cursor diff --git a/pkg/images/tv/iis/lumatch.cl b/pkg/images/tv/iis/lumatch.cl new file mode 100644 index 00000000..1890152b --- /dev/null +++ b/pkg/images/tv/iis/lumatch.cl @@ -0,0 +1,8 @@ +#{ LUMATCH -- Match the lookup tables for two frames. + +# frame,i,a,,1,4,frame to be adjusted +# ref_frame,i,a,,1,4,reference frame + +{ + _dcontrol (frame=frame, alternate=ref_frame, match=yes) +} diff --git a/pkg/images/tv/iis/lumatch.par b/pkg/images/tv/iis/lumatch.par new file mode 100644 index 00000000..60e3b7b3 --- /dev/null +++ b/pkg/images/tv/iis/lumatch.par @@ -0,0 +1,2 @@ +frame,i,a,,1,4,frame to be adjusted +ref_frame,i,a,,1,4,frame to be matched diff --git a/pkg/images/tv/iis/mkpkg b/pkg/images/tv/iis/mkpkg new file mode 100644 index 00000000..7b45b437 --- /dev/null +++ b/pkg/images/tv/iis/mkpkg @@ -0,0 +1,25 @@ +# Make the CV (Control Video) display load and control package. + +$call relink +$exit + +update: + $call relink + $call install + ; + +relink: + $update libpkg.a + $omake x_iis.x + $link x_iis.o libpkg.a -o xx_iis.e + ; + +install: + $move xx_iis.e bin$x_iis.e + ; + +libpkg.a: + @ids + @iism70 + @src + ; diff --git a/pkg/images/tv/iis/monochrome.cl b/pkg/images/tv/iis/monochrome.cl new file mode 100644 index 00000000..91de948f --- /dev/null +++ b/pkg/images/tv/iis/monochrome.cl @@ -0,0 +1,5 @@ +#{ MONOCHROME -- Set monochrome enhancement on display. + +{ + _dcontrol (map="mono") +} diff --git a/pkg/images/tv/iis/pseudocolor.cl b/pkg/images/tv/iis/pseudocolor.cl new file mode 100644 index 00000000..74d66a82 --- /dev/null +++ b/pkg/images/tv/iis/pseudocolor.cl @@ -0,0 +1,24 @@ +#{ PSEUDOCOLOR -- Select pseudocolor enhancement. + +# enhancement,s,a,linear,,,"type of pseudocolor enhancement:\n\ +# linear - map greyscale into a spectrum\n\ +# random - one randomly chosen color is assigned each greylevel\n\ +# 8color - eight random colors\n\ +# enter selection" +# window,b,h,yes,,,window display after enabling pseudocolor +# enhance,s,h + +{ + # Query for enchancement and copy into local param, otherwise each + # reference will cause a query. + enhance = enhancement + + if (enhance == "linear") + _dcontrol (map = "linear", window=window) + else if (enhance == "random") + _dcontrol (map = "random", window=window) + else if (enhance == "8color") + _dcontrol (map = "8color", window=window) + else + error (0, "unknown enhancement") +} diff --git a/pkg/images/tv/iis/pseudocolor.par b/pkg/images/tv/iis/pseudocolor.par new file mode 100644 index 00000000..e99d8d80 --- /dev/null +++ b/pkg/images/tv/iis/pseudocolor.par @@ -0,0 +1,7 @@ +enhancement,s,a,random,,,"type of pseudocolor enhancement:\n\ + linear - map greyscale into a spectrum\n\ + random - a randomly chosen color is assigned to each greylevel\n\ + 8color - use eight colors chosen at random\n\ +enter selection" +window,b,h,yes,,,window display after enabling pseudocolor +enhance,s,h diff --git a/pkg/images/tv/iis/rgb.cl b/pkg/images/tv/iis/rgb.cl new file mode 100644 index 00000000..4fada018 --- /dev/null +++ b/pkg/images/tv/iis/rgb.cl @@ -0,0 +1,11 @@ +#{ RGB -- Select rgb display mode. + +# red_frame,i,a,1,1,4,red frame +# green_frame,i,a,2,1,4,green frame +# blue_frame,i,a,3,1,4,blue frame +# window,b,h,no,,,window RGB frames + +{ + _dcontrol (type="rgb", red_frame=red_frame, green_frame=green_frame, + blue_frame=blue_frame, rgb_window=window) +} diff --git a/pkg/images/tv/iis/rgb.par b/pkg/images/tv/iis/rgb.par new file mode 100644 index 00000000..86d11871 --- /dev/null +++ b/pkg/images/tv/iis/rgb.par @@ -0,0 +1,4 @@ +red_frame,i,a,1,1,4,red frame +green_frame,i,a,2,1,4,green frame +blue_frame,i,a,3,1,4,blue frame +window,b,h,no,,,window RGB frames diff --git a/pkg/images/tv/iis/src/blink.x b/pkg/images/tv/iis/src/blink.x new file mode 100644 index 00000000..fc176f7a --- /dev/null +++ b/pkg/images/tv/iis/src/blink.x @@ -0,0 +1,132 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctotok.h> +include <ctype.h> +include <gki.h> +include "../lib/ids.h" + +# BLINK -- blink the display. + +procedure blink() + +char token[SZ_LINE] +int tok, count, rate +int sets, button, i +int ctoi(), ip +pointer sp, setp, ptr +int cv_rdbut() +int val, nchar + +define errmsg 10 + +include "cv.com" + +begin + # get rate for blink + + call gargtok (tok, token, SZ_LINE) + if (tok != TOK_NUMBER) { + call eprintf ("Bad blink rate: %s\n") + call pargstr (token) + return + } + ip = 1 + count = ctoi(token, ip, rate) + if (rate < 0) { + call eprintf ("negative rate not legal\n") + return + } + + call smark (sp) + # The "3" is to hold frame/color/quad for one frame; + # the "2" is to allow duplication of each frame so that + # some frames can stay "on" longer. The extra "1" is for graphics. + call salloc (setp, 2 * 3 * (cv_maxframes+1), TY_POINTER) + sets = 0 + + # which frames to blink + + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + while ( (sets <= cv_maxframes+1) && (tok != TOK_NEWLINE) ) { + sets = sets + 1 + ptr = setp + (3 * (sets-1)) + call salloc (Memi[ptr], IDS_MAXIMPL+1, TY_SHORT) + if (tok == TOK_IDENTIFIER) { + if (token[1] == 'f') { + call cv_frame (token[2], Mems[Memi[ptr]]) + if (Mems[Memi[ptr]] == ERR) { + call sfree (sp) + return + } + } + } else if (tok == TOK_NUMBER) { + ip = 1 + nchar = ctoi (token[1], ip, val) + if ( (val < 0) || (val > cv_maxframes)) { + call eprintf ("illegal frame value: %s\n") + call pargstr (token) + call sfree (sp) + return + } + Mems[Memi[ptr]] = val + Mems[Memi[ptr]+1] = IDS_EOD + } else { +errmsg + call eprintf ("Unexpected input: %s\n") + call pargstr (token) + call sfree (sp) + return + } + ptr = ptr + 1 + call salloc (Memi[ptr], IDS_MAXGCOLOR+1, TY_SHORT) + call salloc (Memi[ptr+1], 5, TY_SHORT) + Mems[Memi[ptr]] = IDS_EOD # default all colors + Mems[Memi[ptr+1]] = IDS_EOD # default all quads + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + if ( (tok != TOK_IDENTIFIER) && (tok != TOK_NEWLINE)) + goto errmsg + if ((tok == TOK_IDENTIFIER) && (token[1] == 'c')) { + call cv_color (token[2], Mems[Memi[ptr]]) + if (Mems[Memi[ptr]] == ERR) { + call sfree (sp) + return + } + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + } + if ( (tok != TOK_IDENTIFIER) && (tok != TOK_NEWLINE)) + goto errmsg + if ((tok == TOK_IDENTIFIER) && (token[1] == 'q')) { + call cv_quad (token[2], Mems[Memi[ptr+1]]) + if (Mems[Memi[ptr+1]] == ERR) { + call sfree (sp) + return + } + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + } + } # end while + + button = cv_rdbut() # clear any buttons pressed + call eprintf ("Press any button to terminate blink\n") + repeat { + do i = 1, sets { + ptr = setp + 3 * (i-1) + call cvdisplay (IDS_ON, IDS_DISPLAY_I, Mems[Memi[ptr]], + Mems[Memi[ptr+1]], Mems[Memi[ptr+2]]) + # Delay for "rate*100" milliseconds + call zwmsec (rate * 100) + + # Leave something on screen when button pushed + button = cv_rdbut() + if (button > 0) + break + call cvdisplay (IDS_OFF, IDS_DISPLAY_I, Mems[Memi[ptr]], + Mems[Memi[ptr+1]], Mems[Memi[ptr+2]]) + } + } until (button > 0) + + call sfree (sp) +end diff --git a/pkg/images/tv/iis/src/clear.x b/pkg/images/tv/iis/src/clear.x new file mode 100644 index 00000000..60cf69eb --- /dev/null +++ b/pkg/images/tv/iis/src/clear.x @@ -0,0 +1,48 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctotok.h> +include <ctype.h> +include "../lib/ids.h" + +# CLEAR -- clear certain frames in the display + +procedure clear() + +char token[SZ_LINE] +int tok +short frames[IDS_MAXIMPL+1] + +define nexttok 10 + +include "cv.com" + +begin + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + + while ( (tok == TOK_IDENTIFIER) || (tok == TOK_NUMBER) ) { + if (tok == TOK_IDENTIFIER) { + switch (token[1]) { + case 'a', 'g': + # all colors + call cvclearg (short(IDS_EOD), short (IDS_EOD)) + if (token[1] == 'g') + goto nexttok + frames[1] = IDS_EOD + + case 'f': + call cv_frame (token[2], frames) + } + } else + call cv_frame (token[1], frames) + + call cvcleari (frames) + if (token[1] == 'a') + return + + # get next token +nexttok + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + } +end diff --git a/pkg/images/tv/iis/src/cv.com b/pkg/images/tv/iis/src/cv.com new file mode 100644 index 00000000..ec9c70e7 --- /dev/null +++ b/pkg/images/tv/iis/src/cv.com @@ -0,0 +1,16 @@ +# common block for cv + +pointer cv_gp # file descriptor to write +pointer cv_stack # working space for escape sequences +int cv_maxframes # device max frames +int cv_maxgraph # device max graph planes +int cv_xcen, cv_ycen # user pixel coords of center of dev. +int cv_xres, cv_yres # device resolution +int cv_zres # device z resolution +real cv_xcon, cv_ycon # conversion from NDC to GKI +int cv_grch # graphics channel +real cv_xwinc, cv_ywinc # cursor position for window command + +common /cvcom/ cv_gp, cv_stack, cv_maxframes, cv_maxgraph, cv_xcen, cv_ycen, + cv_xres, cv_yres, cv_zres, cv_xcon, cv_ycon, cv_grch, + cv_xwinc, cv_ywinc diff --git a/pkg/images/tv/iis/src/cv.h b/pkg/images/tv/iis/src/cv.h new file mode 100644 index 00000000..80f3016b --- /dev/null +++ b/pkg/images/tv/iis/src/cv.h @@ -0,0 +1,51 @@ +# constants for cv package...should come from a graphcap entry + +# These are one based. +define CV_XCEN 257 +define CV_YCEN 256 + +define CV_XRES 512 +define CV_YRES 512 +define CV_ZRES 256 + +define CV_MAXF 4 +define CV_MAXG 7 + +define CV_GRCHNUM 16 + +# CVLEN is just the *estimated* never to be exceeded amount of storage needed +# to set up the escape sequence. It could be determined dynamically by +# changing cv_move to count elements instead of moving them. Then the known +# counts would be used with amovs to hustle the elements into the "salloc'ed" +# space. Instead, with a static count, we can salloc once upon entering +# the cv program and free up at exit. + +define CVLEN 128 + +# Following are from "display.h"... only SAMPLE_SIZE and MAXLOG needed +# as of May, 1985. But we might incorporate other programs from "tv", +# so leave them. + +# Size limiting parameters. + +define MAXCHAN 2 +define SAMPLE_SIZE 600 + +# If a logarithmic greyscale transformation is desired, the input range Z1:Z2 +# will be mapped into the range 1.0 to 10.0 ** MAXLOG before taking the log +# to the base 10. + +define MAXLOG 3 + +# The following parameter is used to compare display pixel coordinates for +# equality. It determines the maximum permissible magnification. The machine +# epsilon is not used because the computations are nontrivial and accumulation +# of error is a problem. + +define DS_TOL (1E-4) + +# These parameters are needed for user defined transfer functions. + +define SZ_BUF 4096 +define STARTPT 0.0E0 +define ENDPT 4095.0E0 diff --git a/pkg/images/tv/iis/src/cv.x b/pkg/images/tv/iis/src/cv.x new file mode 100644 index 00000000..a169a402 --- /dev/null +++ b/pkg/images/tv/iis/src/cv.x @@ -0,0 +1,175 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <fio.h> +include <fset.h> +include "../lib/ids.h" +include <gki.h> +include <ctotok.h> +include <error.h> +include "cv.h" + +# Captain Video + +procedure t_cv() + +pointer gp +char device[SZ_FNAME] +char command[SZ_LINE] + +pointer gopen(), sp +int dd[LEN_GKIDD] + +int scan, tok, envgets() + +include "cv.com" + +begin + call smark (sp) + call salloc (cv_stack, CVLEN, TY_SHORT) + + if (envgets ("stdimage", device, SZ_FNAME) == 0) + call error (EA_FATAL, + "variable 'stdimage' not defined in environment") + + call ids_open (device, dd) + call gki_inline_kernel (STDIMAGE, dd) + gp = gopen ( device, READ_WRITE, STDIMAGE) + + call fseti (STDIMAGE, F_TYPE, SPOOL_FILE) + call fseti (STDIMAGE, F_CANCEL, OK) + call ids_grstream (STDIMAGE) + + # to do: + # initialize local variables: image display size, etc + # instead of defines such as MCXSCALE, etc + cv_maxframes = CV_MAXF + cv_maxgraph = CV_MAXG + cv_xcen = CV_XCEN + cv_ycen = CV_YCEN + cv_xres = CV_XRES + cv_yres = CV_YRES + cv_zres = CV_ZRES + cv_gp = gp + cv_xcon = real(GKI_MAXNDC+1)/CV_XRES + cv_ycon = real(GKI_MAXNDC+1)/CV_YRES + cv_grch = CV_GRCHNUM + cv_xwinc = -1. # Flag: Don't know what lut is + + repeat { + call printf (":-) ") + call flush (STDOUT) + if (scan() == EOF) + break + call gargtok(tok, command, SZ_LINE) + if ((tok == TOK_EOS) || (tok == TOK_NEWLINE)) + next + # decode next command + call strlwr(command) + switch (command[1]) { + case 'x', 'q': + break + + + case 'b': + call blink + + case 'c': + if (command[2] == 'l') + call clear + else + call rdcur + + case 'd': + call display(command[2]) + + case 'e': # erase means clear + call clear + + case 'h', '?': + call help + + # case 'l': + # call load + + case 'm': + call match + + case 'o': + call offset + + case 'p': + if ( command[2] == 's') + call map(command[2]) # pseudo color + else + call pan + + case 'r': + if (command[2] == 'e') + call reset + else + call range + + case 's': + if (command[2] == 'n') + call snap + else + call split + + case 't': + call tell + + case 'w': + if (command[2] == 'r') + call text + else + call window + + case 'z': + call zoom + + default: + call eprintf("unknown command: %s\n") + call pargstr(command[1]) + + } # end switch statement + + } # end repeat statment + + # all done + + call gclose ( gp ) + call ids_close + call sfree (sp) +end + + +# HELP -- print informative message + +procedure help() + +begin + call eprintf ("--- () : optional; [] : select one; N : number; C/F/Q : see below\n") + call eprintf ("b(link) N F (C Q) (F (C Q)..) blink N = 10 is one second\n") + call eprintf ("c(ursor) [on off F] cursor\n") + call eprintf ("di F (C Q) [on off] display image\n") + call eprintf ("dg C (F Q) [on off] display graphics\n") + call eprintf ("e(rase) [N a(ll) g(raphics) F] erase (clear)\n") + #call eprintf ("l(oad) load a frame\n") + call eprintf ("m(atch) (o) F (C) (to) (F) (C) match (output) lookup table\n") + call eprintf ("o(ffset) C N offset color N: 0 to +- 4095\n") + call eprintf ("p(an) (F) pan images\n") + call eprintf ("ps(eudo) (o) (F C) (rn sn) pseudo color mapping rn/sn: random n/seed n\n") + call eprintf ("r(ange) N (C) (N C ...) scale image N: 1-8\n") + call eprintf ("re(set) [r i t a] reset display registers/image/tables/all\n") + call eprintf ("sn(ap) (C) snap a picture\n") + call eprintf ("s(plit) [c o px,y nx,y] split picture\n") + call eprintf ("t(ell) tell display state\n") + call eprintf ("w(indow) (o) (F C) window (output) frames\n") + call eprintf ("wr(ite) [F C] text write text to frame/graphics\n") + call eprintf ("z(oom) N (F) zoom frames N: 1-8\n") + call eprintf ("x or q exit/quit\n") + call eprintf ("--- C: letter c followed by r/g/b/a or, for snap r,g,b,m,bw,rgb,\n") + call eprintf ("--- or for dg r/g/b/y/p/m/w, as 'cr', 'ca', or 'cgb'\n") + call eprintf ("--- F: f followed by a frame number or 'a' for all\n") + call eprintf ("--- Q: q followed by quadrant number or t,b,l,r for top, bottom,...\n") +end diff --git a/pkg/images/tv/iis/src/cvparse.x b/pkg/images/tv/iis/src/cvparse.x new file mode 100644 index 00000000..46aba66b --- /dev/null +++ b/pkg/images/tv/iis/src/cvparse.x @@ -0,0 +1,196 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "../lib/ids.h" +include <ctype.h> + +# CVPARSE -- parsing routines for the cv package + +# CV_FRAME -- parse a frame specification + +procedure cv_frame(str, result) + +char str[ARB] # input string +short result[ARB] # result string + +int ip +int op +int i +int used[IDS_MAXIMPL] +int gused + +include "cv.com" + +begin + if (str[1] == 'a') { + result[1] = IDS_EOD + return + } + call aclrs(used,IDS_MAXIMPL) + gused = 0 + op = 1 + for (ip = 1; str[ip] != EOS; ip = ip + 1) { + if (!IS_DIGIT(str[ip])) { + if (str[ip] == 'g') + gused = 1 + else { + call eprintf("unknown frame specifier: %c\n") + call pargc(str[ip]) + } + next + } + i = TO_INTEG (str[ip]) # fail if > than 9 planes! use ctoi() + if ((i < 1) || (i > cv_maxframes) ) { + call eprintf ("out of bounds frame: %d\n") + call pargi(i) + next + } else + used[i] = 1 + } + do i= 1,IDS_MAXIMPL + if (used[i] != 0) { + result[op] = i + op = op + 1 + } + if (gused != 0) { + result[op] = cv_grch + op = op + 1 + } + if (op > 1) + result[op] = IDS_EOD + else + result[op] = ERR +end + + +# CV_COLOR -- parse a color specification + +procedure cv_color(str, result) + +char str[ARB] # input string +short result[ARB] # result string + +int ip +int op +int i +short val +short used[IDS_MAXGCOLOR+1] + +include "cv.com" + +begin + if (str[1] == 'a') { + result[1] = IDS_EOD + return + } + call aclrs (used, IDS_MAXGCOLOR+1) + op = 1 + for (ip = 1; str[ip] != EOS; ip = ip + 1) { + switch (str[ip]) { + case 'r': + val = IDS_RED + + case 'g': + val = IDS_GREEN + + case 'b': + val = IDS_BLUE + + case 'y': + val = IDS_YELLOW + + case 'w': + val = IDS_WHITE + + case 'p': + val = IDS_RDBL + + case 'm': + val = IDS_GRBL + + default: + call eprintf("unknown color: %c\n") + call pargc(str[ip]) + next + } + used[val] = 1 + } + do i = 1, IDS_MAXGCOLOR+1 + if (used[i] != 0) { + result[op] = i + op = op + 1 + } + if (op > 1) + result[op] = IDS_EOD + else + result[op] = ERR +end + + +# CV_QUAD -- parse a quad specification + +procedure cv_quad(str, result) + +char str[ARB] # input string +short result[ARB] # result string + +int ip +int op +int i +short used[4] + +include "cv.com" + +begin + if (str[1] == 'a') { + result[1] = IDS_EOD + return + } + call aclrs(used, 4) + op = 1 + for (ip = 1; str[ip] != EOS; ip = ip + 1) { + if (!IS_DIGIT(str[ip])) { + switch(str[ip]) { + case 'a': + call amovks (1, used, 4) + + case 't': + used[1] = 1 + used[2] = 1 + + case 'b': + used[3] = 1 + used[4] = 1 + + case 'l': + used[2] = 1 + used[3] = 1 + + case 'r': + used[1] = 1 + used[4] = 1 + + default: + call eprintf("unknown quad specifier: %c\n") + call pargc(str[ip]) + } + } else { + i = TO_INTEG (str[ip]) + if ((i < 1) || (i > 4)) { + call eprintf ("out of bounds quad: %d\n") + call pargi(i) + next + } else + used[i] = 1 + } + } + do i = 1,4 { + if (used[i] != 0) { + result[op] = i + op = op + 1 + } + } + if (op > 1) + result[op] = IDS_EOD + else + result[op] = ERR +end diff --git a/pkg/images/tv/iis/src/cvulut.x b/pkg/images/tv/iis/src/cvulut.x new file mode 100644 index 00000000..683c9500 --- /dev/null +++ b/pkg/images/tv/iis/src/cvulut.x @@ -0,0 +1,130 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <error.h> +include <ctype.h> +include "cv.h" + +# CV_ULUT -- Generates a look up table from data supplied by user. The +# data is read from a two column text file of intensity, greyscale values. +# The input data are sorted, then mapped to the x range [0-4096]. A +# piecewise linear look up table of 4096 values is then constructed from +# the (x,y) pairs given. A pointer to the look up table, as well as the z1 +# and z2 intensity endpoints, is returned. + +procedure cv_ulut (fname, z1, z2, lut) + +char fname[SZ_FNAME] # Name of file with intensity, greyscale values +real z1 # Intensity mapped to minimum gs value +real z2 # Intensity mapped to maximum gs value +pointer lut # Look up table - pointer is returned + +pointer sp, x, y +int nvalues, i, j, x1, x2, y1 +real delta_gs, delta_xv, slope +errchk cv_rlut, cv_sort, malloc + +begin + call smark (sp) + call salloc (x, SZ_BUF, TY_REAL) + call salloc (y, SZ_BUF, TY_REAL) + + # Read intensities and greyscales from the user's input file. The + # intensity range is then mapped into a standard range and the + # values sorted. + + call cv_rlut (fname, Memr[x], Memr[y], nvalues) + call alimr (Memr[x], nvalues, z1, z2) + call amapr (Memr[x], Memr[x], nvalues, z1, z2, STARTPT, ENDPT) + call cv_sort (Memr[x], Memr[y], nvalues) + + # Fill lut in straight line segments - piecewise linear + call malloc (lut, SZ_BUF, TY_SHORT) + do i = 1, nvalues-1 { + delta_gs = Memr[y+i] - Memr[y+i-1] + delta_xv = Memr[x+i] - Memr[x+i-1] + slope = delta_gs / delta_xv + x1 = int (Memr[x+i-1]) + x2 = int (Memr[x+i]) + y1 = int (Memr[y+i-1]) + do j = x1, x2-1 + Mems[lut+j-1] = y1 + slope * (j-x1) + } + + call sfree (sp) +end + + +# CV_RLUT -- Read text file of x, y, values. + +procedure cv_rlut (utab, x, y, nvalues) + +char utab[SZ_FNAME] # Name of list file +real x[SZ_BUF] # Array of x values, filled on return +real y[SZ_BUF] # Array of y values, filled on return +int nvalues # Number of values in x, y vectors - returned + +int n, fd +pointer sp, lbuf, ip +real xval, yval +int getline(), open() +errchk open, sscan, getline, malloc + +begin + call smark (sp) + call salloc (lbuf, SZ_LINE, TY_CHAR) + + iferr (fd = open (utab, READ_ONLY, TEXT_FILE)) + call error (0, "Error opening user table") + + n = 0 + + while (getline (fd, Memc[lbuf]) != EOF) { + # Skip comment lines and blank lines. + if (Memc[lbuf] == '#') + next + for (ip=lbuf; IS_WHITE(Memc[ip]); ip=ip+1) + ; + if (Memc[ip] == '\n' || Memc[ip] == EOS) + next + + # Decode the points to be plotted. + call sscan (Memc[ip]) + call gargr (xval) + call gargr (yval) + + n = n + 1 + if (n > SZ_BUF) + call error (0, + "Intensity transformation table cannot exceed 4096 values") + + x[n] = xval + y[n] = yval + } + + nvalues = n + call close (fd) + call sfree (sp) +end + + +# CV_SORT -- Bubble sort of paired arrays. + +procedure cv_sort (xvals, yvals, nvals) + +real xvals[nvals] # Array of x values +real yvals[nvals] # Array of y values +int nvals # Number of values in each array + +int i, j +real temp +define swap {temp=$1;$1=$2;$2=temp} + +begin + for (i = nvals; i > 1; i = i - 1) + for (j = 1; j < i; j = j + 1) + if (xvals[j] > xvals[j+1]) { + # Out of order; exchange y values + swap (xvals[j], xvals[j+1]) + swap (yvals[j], yvals[j+1]) + } +end diff --git a/pkg/images/tv/iis/src/cvutil.x b/pkg/images/tv/iis/src/cvutil.x new file mode 100644 index 00000000..81721081 --- /dev/null +++ b/pkg/images/tv/iis/src/cvutil.x @@ -0,0 +1,538 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <gset.h> +include <gki.h> +include <imhdr.h> +include "cv.h" +include "../lib/ids.h" + +# CVUTIL -- utility control routines for cv package + +############ CLEAR display ############ +# CVCLEARG -- clear all of graphics (bit) planes + +procedure cvclearg (frame, color) + +short frame[ARB] +short color[ARB] + +int count +int cv_move() + +include "cv.com" + +begin + count = cv_move (frame, Mems[cv_stack]) + count = count + cv_move (color, Mems[cv_stack+count]) + call gescape (cv_gp, IDS_SET_GP, Mems[cv_stack], count) + call gclear (cv_gp) +end + +# CVCLEARI -- clear specified image frames + +procedure cvcleari (frames) + +short frames[ARB] + +include "cv.com" + +begin + call cv_iset (frames) + call gclear (cv_gp) +end + +############ CURSOR and BUTTON ############ +# CV_RDBUT -- read button on trackball (or whatever) +# if none pressed, will get zero back + +int procedure cv_rdbut() + +int oldcnum +real x, y +int button +int gstati + +include "cv.com" + +begin + oldcnum = gstati (cv_gp, G_CURSOR) + call gseti (cv_gp, G_CURSOR, IDS_BUT_RD) + call ggcur (cv_gp, x, y, button) + call gseti (cv_gp, G_CURSOR, oldcnum) + return(button) +end + +# CV_WTBUT -- wait for button to be pressed, then read it + +int procedure cv_wtbut() + +int oldcnum +real x, y +int button +int gstati + +include "cv.com" + +begin + oldcnum = gstati (cv_gp, G_CURSOR) + call gseti (cv_gp, G_CURSOR, IDS_BUT_WT) + call ggcur (cv_gp, x, y, button) + call gseti (cv_gp, G_CURSOR, oldcnum) + return(button) +end + +# CV_RCUR -- read cursor. The cursor read/set routines do not restore +# the cursor number...this to avoid numerous stati/seti calls that +# usually are not needed. + +procedure cv_rcur (cnum, x, y) + +int cnum +real x,y +int junk + +include "cv.com" + +begin + call gseti (cv_gp, G_CURSOR, cnum) + call ggcur (cv_gp, x, y, junk) +end + +# CV_SCUR -- set cursor + +procedure cv_scur (cnum, x, y) + +int cnum +real x,y + +include "cv.com" + +begin + call gseti (cv_gp, G_CURSOR, cnum) + call gscur (cv_gp, x, y) +end + + +# CV_RCRAW -- read the raw cursor (return actual screen coordinates). + +procedure cv_rcraw (x, y) + +real x,y + +include "cv.com" + +begin + call cv_rcur (IDS_CRAW, x, y) +end + +# CV_SCRAW -- set raw cursor + +procedure cv_scraw (x, y) + +real x,y + +include "cv.com" + +begin + call cv_scur (IDS_CRAW, x, y) +end + + +# cvcur -- turn cursor on or off + +procedure cvcur (instruction) + +int instruction + +include "cv.com" + +begin + Mems[cv_stack] = IDS_CURSOR + Mems[cv_stack+1] = IDS_WRITE + Mems[cv_stack+2] = 1 + Mems[cv_stack+3] = IDS_EOD + Mems[cv_stack+4] = IDS_EOD + Mems[cv_stack+5] = 1 + Mems[cv_stack+6] = instruction + call gescape (cv_gp, IDS_CONTROL, Mems[cv_stack], 7) +end + +############ DISPLAY ############ +# cvdisplay + +procedure cvdisplay (instruction, device, frame, color, quad) + +int instruction +int device +short frame, color, quad + +int i +int cv_move() + +include "cv.com" + +begin + Mems[cv_stack] = instruction + i = cv_move (frame, Mems[cv_stack+1]) + i = i + cv_move (color, Mems[cv_stack+1+i]) + i = i + cv_move (quad, Mems[cv_stack+1+i]) + call gescape (cv_gp, device, Mems[cv_stack], 1+i) +end + +############ MATCH ############ +# cvmatch -- build match escape sequence + +procedure cvmatch (lt, fr, cr, frames, color) + +int lt # type +short fr[ARB] # reference frame and color +short cr[ARB] +short frames[ARB] # frames to be changed +short color[ARB] # and colors + +int count, n +int cv_move() + +include "cv.com" + +begin + Mems[cv_stack] = IDS_MATCH + Mems[cv_stack+1] = lt + count = cv_move (fr, Mems[cv_stack+3]) + count = count + cv_move (cr, Mems[cv_stack+3+count]) + n = count + Mems[cv_stack+count+3] = 0 # unused offset + count = count + cv_move (frames, Mems[cv_stack+4+count]) + count = count + cv_move (color, Mems[cv_stack+4+count]) + Mems[cv_stack+2] = count - n + call gescape (cv_gp, IDS_CONTROL, Mems[cv_stack], count+4) +end + +############ OFFSET ############ +# cvoffset -- set offset registers + +procedure cvoffset( color, data) + +short color[ARB] +short data[ARB] + +int count, cv_move() +int i + +include "cv.com" + +begin + Mems[cv_stack] = IDS_OUT_OFFSET + Mems[cv_stack+1] = IDS_WRITE + Mems[cv_stack+3] = IDS_EOD # no-op the frames slot + count = cv_move (color, Mems[cv_stack+4]) + Mems[cv_stack+4+count] = 1 # (unused) offset + i = cv_move (data, Mems[cv_stack+5+count]) + i = i - 1 # don't include EOD of "data" + Mems[cv_stack+2] = i + call gescape (cv_gp, IDS_CONTROL, Mems[cv_stack], i+count+5) +end + +############ PAN ############ +# cvpan -- move the image(s) around +# The x,y coordinates are NDC that, it is assumed, came from a cursor +# read, and therefore are of the form +# ((one_based_pixel-1)/(resolution)) *(GKI_MAXNDC+1) / GKI_MAXNDC +# The division by GKI_MAXNDC turns into NDC what was GKI ranging from +# 0 through 511*64 (for IIS) which conforms to the notion of specifying +# each pixel by its left/bottom GKI boundary. + +procedure cvpan (frames, x, y) + +short frames[ARB] +real x,y # position in NDC + +int count, cv_move() + +include "cv.com" + +begin + Mems[cv_stack] = IDS_SCROLL + Mems[cv_stack+1] = IDS_WRITE + Mems[cv_stack+2] = 3 + count = cv_move (frames, Mems[cv_stack+3]) + Mems[cv_stack+3+count] = IDS_EOD # all colors + Mems[cv_stack+4+count] = 1 # (unused) offset + Mems[cv_stack+5+count] = x * GKI_MAXNDC + Mems[cv_stack+6+count] = y * GKI_MAXNDC + Mems[cv_stack+7+count] = IDS_EOD # for all frames + call gescape (cv_gp, IDS_CONTROL, Mems[cv_stack], count+8) +end + +############ RANGE ############ +# cvrange -- scale ouput before final look up table + +procedure cvrange ( color, range) + +short color[ARB] +short range[ARB] + +int cv_move(), count, i + +include "cv.com" + +begin + Mems[cv_stack] = IDS_RANGE + Mems[cv_stack+1] = IDS_WRITE + Mems[cv_stack+3] = IDS_EOD # all frames + count = cv_move (color, Mems[cv_stack+4]) + Mems[cv_stack+4+count] = 1 # (unused) offset + i = cv_move (range, Mems[cv_stack+5+count]) + i = i - 1 # don't include EOD of "range" + Mems[cv_stack+2] = i + call gescape (cv_gp, IDS_CONTROL, Mems[cv_stack], i+count+5) +end + +############ RESET display ############ +# cvreset -- reset display +# SOFT -- everything but lookup tables and image/graphics planes +# MEDIUM -- everything but image/graphics planes +# HARD -- everything...planes are cleared, all images OFF + +procedure cvreset (hardness) + +int hardness + +include "cv.com" + +begin + Mems[cv_stack] = hardness + call gescape (cv_gp, IDS_RESET, Mems[cv_stack], 1) +end + + +############ SNAP a picture ############ +# cvsnap -- takes a full picture of image display + +procedure cvsnap (fname, snap_color) + +char fname[ARB] # image file name +int snap_color + +pointer im, immap(), impl2s() +int i, factor +real y + +include "cv.com" + +begin + im = immap(fname, NEW_FILE, 0) + IM_PIXTYPE(im) = TY_SHORT + IM_LEN(im,1) = cv_xres + IM_LEN(im,2) = cv_yres + + Mems[cv_stack] = IDS_SNAP + Mems[cv_stack+1] = IDS_WRITE + Mems[cv_stack+2] = 1 # frame, color are not relevant + Mems[cv_stack+3] = IDS_EOD + Mems[cv_stack+4] = IDS_EOD + Mems[cv_stack+5] = 0 + Mems[cv_stack+6] = snap_color + call gescape (cv_gp, IDS_CONTROL, Mems[cv_stack], 7) + + factor = cv_yres/10 + 1 + call eprintf (" (%% done: ") + call flush (STDERR) + do i = 0, cv_yres-1 { + if ( mod(i,factor) == 0) { + call eprintf ("%d ") + call pargi (int(10*i/cv_yres)*10) + call flush (STDERR) + } + y = real(i)*cv_ycon / GKI_MAXNDC. + call ggcell (cv_gp, Mems[impl2s(im,i+1)], cv_xres, 1, 0.0, + y, 1.0, y) + } + call eprintf ("100)\n") + + call imunmap(im) + Mems[cv_stack] = IDS_R_SNAPDONE + call gescape (cv_gp, IDS_RESET, Mems[cv_stack], 1) +end + +############ SPLIT ############ +# cvsplit -- set split screen position + +procedure cvsplit (x, y) + +real x,y # NDC coordinates + +include "cv.com" + +begin + Mems[cv_stack] = IDS_SPLIT + Mems[cv_stack+1] = IDS_WRITE + Mems[cv_stack+2] = 2 + Mems[cv_stack+3] = IDS_EOD # no-op frame and color + Mems[cv_stack+4] = IDS_EOD + Mems[cv_stack+5] = 1 # (unused) offset + # NOTE multiplacation by MAXNDC+1 ... x, and y, are never == 1.0 + # ( see split.x) + # and truncation effects will work out just right, given what the + # image display kernel does with these numbers + Mems[cv_stack+6] = x * (GKI_MAXNDC+1) + Mems[cv_stack+7] = y * (GKI_MAXNDC+1) + call gescape (cv_gp, IDS_CONTROL, Mems[cv_stack], 8) +end + +############ TEXT ############ +# Write text + +procedure cvtext (x, y, text, size) + +real x, y, size +char text[ARB] + +char format[SZ_LINE] + +include "cv.com" + +begin + call sprintf (format, SZ_LINE, "s=%f") + call pargr (size) + call gtext (cv_gp, x, y, text, format) +end + +############ WHICH ############ +# Tell which frames are one. The best we can do now is +# tell if any, and if so, which is the "first" + +procedure cvwhich (fr) + +short fr[ARB] + +real x,y +int cnum, oldcnum +int gstati + +include "cv.com" + +begin + # Use here the fact that if cursor number is zero, the + # kernel will return the number of the first displayed + # frame, or "ERR" if none. + oldcnum = gstati (cv_gp, G_CURSOR) + cnum = 0 + call gseti (cv_gp, G_CURSOR, cnum) + call ggcur (cv_gp, x, y, cnum) + call gseti (cv_gp, G_CURSOR, oldcnum) + fr[1] = cnum + fr[2] = IDS_EOD +end + +############ WLUT ############ +# cvwlut ... change lookup tables +# the data is in form of line endpoints. + +procedure cvwlut (device, frames, color, data, n) + +int device +short frames[ARB] +short color[ARB] +short data[ARB] +int n + +int count, cv_move() + +include "cv.com" + +begin + # Device had better refer to a look-up table, or who knows + # what will happen! + Mems[cv_stack] = device + Mems[cv_stack+1] = IDS_WRITE + Mems[cv_stack+2] = n + count = cv_move (frames, Mems[cv_stack+3]) + count = count + cv_move (color, Mems[cv_stack+3+count]) + Mems[cv_stack+3+count] = 1 # (unused) offset + call amovs (data, Mems[cv_stack+count+4],n) + call gescape (cv_gp, IDS_CONTROL, Mems[cv_stack], n+count+4) +end + +############ ZOOM ############ +# cvzoom -- zoom the image +# See comment under PAN about x and y. + +procedure cvzoom (frames, power, x, y) + +short frames[ARB] +int power +real x,y + +int count, cv_move() + +include "cv.com" + +begin + Mems[cv_stack] = IDS_ZOOM + Mems[cv_stack+1] = IDS_WRITE + Mems[cv_stack+2] = 3 + count = cv_move (frames, Mems[cv_stack+3]) + Mems[cv_stack+3+count] = IDS_EOD # (unused) color + Mems[cv_stack+4+count] = IDS_EOD # (unused) offset + Mems[cv_stack+5+count] = power + Mems[cv_stack+6+count] = x * GKI_MAXNDC + Mems[cv_stack+7+count] = y * GKI_MAXNDC + call gescape (cv_gp, IDS_CONTROL, Mems[cv_stack], count+8) +end + +############ SUBROUTINES ############## +# CV_MOVE -- transfer an array into the escape data array; returns number +# of items transfered. + +int procedure cv_move (in, out) + +short in[ARB] +short out[ARB] + +int count + +begin + count = 0 + repeat { + count = count + 1 + out[count] = in[count] + } until (in[count] == IDS_EOD) + return (count) +end + +# CV_ISET -- Tell the image kernel that i/o is to be done for the +# specified frame/frames. + +procedure cv_iset (frames) + +short frames[ARB] + +short idata[30] +int i, cv_move() + +include "cv.com" + +begin + i = cv_move (frames, idata) + idata[i+1] = IDS_EOD # all bit planes + call gescape (cv_gp, IDS_SET_IP, idata, i+1) +end + +# CV_GSET -- Tell the image kernel that i/o is to be done for the +# specified colors. + +procedure cv_gset (colors) + +short colors[ARB] + +short idata[30] +int i, cv_move() + +include "cv.com" + +begin + idata[1] = IDS_EOD # all "frames" + i = cv_move (colors, idata[2]) + call gescape (cv_gp, IDS_SET_GP, idata, i+1) +end diff --git a/pkg/images/tv/iis/src/display.x b/pkg/images/tv/iis/src/display.x new file mode 100644 index 00000000..d04b1365 --- /dev/null +++ b/pkg/images/tv/iis/src/display.x @@ -0,0 +1,104 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctotok.h> +include <ctype.h> +include "../lib/ids.h" + +# DISPLAY -- Turn frames on or off + +procedure display(command) + +char command[ARB] + +int tok +char token[SZ_LINE] +short color[IDS_MAXGCOLOR+1] +short frames[IDS_MAXIMPL+1] +short quad[5] +short instruction +int escape +include "cv.com" + +begin + if (command[1] == 'i') + escape = IDS_DISPLAY_I + else if (command[1] == 'g') + escape = IDS_DISPLAY_G + else { + call eprintf ("Only 'di' or 'dg' are understood\n") + return + } + + instruction = ERR + frames[1] = ERR + color[1] = ERR + quad[1] = IDS_EOD + + repeat { + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + if ( tok == TOK_IDENTIFIER) { + switch (token[1]) { + case 'c': + call cv_color (token[2], color) + if (color[1] == ERR) + return + + case 'f': + call cv_frame (token[2], frames) + if (frames[1] == ERR) + return + + + case 'o': + if (token[2] == 'n') + instruction = IDS_ON + else if (token[2] == 'f') + instruction = IDS_OFF + + case 'q': + call cv_quad (token[2], quad) + if (quad[1] == ERR) + return + } + } else if (tok == TOK_NUMBER) { + call cv_frame (token[1], frames) + if (frames[1] == ERR) + return + } + } until ( tok == TOK_NEWLINE ) + + + # Require a frame number, but allow default of color and quad to "all". + # But, for graphics, default the frame and require a color. + # In either case, for OFF, allow all defaults. + if (escape == IDS_DISPLAY_I) { + if ((instruction == IDS_OFF) && (frames[1] == ERR)) + frames[1] = IDS_EOD + if ( color[1] == ERR) + color[1] = IDS_EOD + } else { + if ((instruction == IDS_OFF) && ( color[1] == ERR) ) + color[1] = IDS_EOD + if ( frames[1] == ERR) + frames[1] = IDS_EOD + } + + if (frames[1] == ERR) { + call eprintf ("Frame specification required\n") + return + } + if (color[1] == ERR) { + call eprintf ("Color specification required\n") + return + } + + # if neither "on" nor "off", then turn off all, and turn + # on the specified frames + if (instruction == ERR) { + call cvdisplay (IDS_OFF , escape, short(IDS_EOD), + short(IDS_EOD), short(IDS_EOD)) + instruction = IDS_ON + } + call cvdisplay (instruction, escape, frames, color, quad) +end diff --git a/pkg/images/tv/iis/src/gwindow.h b/pkg/images/tv/iis/src/gwindow.h new file mode 100644 index 00000000..5050b304 --- /dev/null +++ b/pkg/images/tv/iis/src/gwindow.h @@ -0,0 +1,34 @@ +# Window descriptor structure. + +define LEN_WDES (5+(W_MAXWC+1)*LEN_WC+80) +define LEN_WC 10 # 4=[XbXeYbYe]+2=tr_type[xy] +define W_MAXWC 5 # max world coord systems +define W_SZIMSECT 79 # image section string + +define W_DEVICE Memi[$1] +define W_FRAME Memi[$1+1] # device frame number +define W_XRES Memi[$1+2] # device resolution, x +define W_YRES Memi[$1+3] # device resolution, y +define W_WC ($1+$2*LEN_WC+5) # ptr to coord descriptor +define W_IMSECT Memc[($1+65-1)*SZ_STRUCT+1] + +# Fields of the WC coordinate descriptor, a substructure of the window +# descriptor. "W_XB(W_WC(w,0))" is the XB field of wc 0 of window W. + +define W_XS Memr[P2R($1)] # starting X value +define W_XE Memr[P2R($1+1)] # ending X value +define W_XT Memi[$1+2] # X transformation type +define W_YS Memr[P2R($1+3)] # starting Y value +define W_YE Memr[P2R($1+4)] # ending Y value +define W_YT Memi[$1+5] # Y transformation type +define W_ZS Memr[P2R($1+6)] # starting Z value (greyscale) +define W_ZE Memr[P2R($1+7)] # ending Z value +define W_ZT Memi[$1+8] # Z transformation type +define W_UPTR Memi[$1+9] # LUT when ZT=USER + +# Types of coordinate and greyscale transformations. + +define W_UNITARY 0 # values map without change +define W_LINEAR 1 # linear mapping +define W_LOG 2 # logarithmic mapping +define W_USER 3 # user specifies transformation diff --git a/pkg/images/tv/iis/src/load1.x b/pkg/images/tv/iis/src/load1.x new file mode 100644 index 00000000..c33cc1dd --- /dev/null +++ b/pkg/images/tv/iis/src/load1.x @@ -0,0 +1,324 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +#### load1.x (from load.x) #### + +include <mach.h> +include <imset.h> +include <imhdr.h> +include <error.h> +include <gki.h> +include <fio.h> +include <fset.h> +include "gwindow.h" +include "../lib/ids.h" +include "cv.h" + +# LOAD - Load an image. The specified image section is mapped into +# the specified section of an image display frame. The mapping involves +# a linear transformation in X and Y and a linear or logarithmic transformation +# in Z (greyscale). Images of all pixel datatypes are supported, and there +# no upper limit on the size of an image. The display device is interfaced +# via GIO metacode. + +procedure t_load() + +char image[SZ_FNAME] +short frame[IDS_MAXIMPL+1] +bool frame_erase, border_erase +pointer im, wdes, sp + +pointer gp +char device[SZ_FNAME] +int dd[LEN_GKIDD] + +int envgets() +short clgets() +bool clgetb() +pointer immap(), gopen() + +include "cv.com" +errchk immap, imunmap, ds_getparams + +begin + call smark (sp) + call salloc (cv_stack, CVLEN, TY_SHORT) + call salloc (wdes, LEN_WDES, TY_STRUCT) + + if (envgets ("stdimage", device, SZ_FNAME) == 0) + call error (EA_FATAL, + "variable 'stdimage' not defined in environment") + + call ids_open (device, dd) + call gki_inline_kernel (STDIMAGE, dd) + # Need READ_WRITE so can call cvdisplay + gp = gopen ( device, READ_WRITE, STDIMAGE) + + call fseti (STDIMAGE, F_TYPE, SPOOL_FILE) + call fseti (STDIMAGE, F_CANCEL, OK) + call ids_grstream (STDIMAGE) + + # to do: + # initialize local variables: image display size, etc + # instead of defines such as MCXSCALE, etc + + cv_maxframes = CV_MAXF + cv_maxgraph = CV_MAXG + cv_xcen = CV_XCEN + cv_ycen = CV_YCEN + cv_xres = CV_XRES + cv_yres = CV_YRES + cv_zres = CV_ZRES + cv_gp = gp + cv_xcon = real(GKI_MAXNDC+1)/CV_XRES + cv_ycon = real(GKI_MAXNDC+1)/CV_YRES + cv_grch = CV_GRCHNUM + cv_xwinc = -1. # Flag: Don't know what lut is + + # Open input imagefile. + call clgstr ("image", image, SZ_FNAME) + im = immap (image, READ_ONLY, 0) + + # Ultimately, we should get a sequence of frames, all of which get + # loaded with the same image. + + frame[1] = clgets ("frame") + frame[2] = IDS_EOD + frame_erase = clgetb ("erase") + + # Optimize for sequential i/o. + call imseti (im, IM_ADVICE, SEQUENTIAL) + + # The frame being displayed does not necessarily change when a new + # frame is loaded. (We might consider letting user select via the + # cv package) + + if (clgetb ("select_frame")) { + call cvdisplay (IDS_OFF, IDS_DISPLAY_I, short(IDS_EOD), + short(IDS_EOD), short(IDS_EOD)) + call cvdisplay (IDS_ON, IDS_DISPLAY_I, frame, short(IDS_EOD), + short(IDS_EOD)) + } + + if (frame_erase) + call cvcleari (frame) + + # Tell GIO what frame(s) to write + call cv_iset (frame) + + # Done with all possible read/write calls to cv package. Fix up so + # don't read device if we erase the frame, so need WRITE_ONLY mode. + # fseti on STDIMAGE didn't work. + + if (frame_erase) { + call gclose (gp) + call gki_inline_kernel (STDIMAGE, dd) + gp = gopen ( device, WRITE_ONLY, STDIMAGE) + cv_gp = gp + call fseti (STDIMAGE, F_TYPE, SPOOL_FILE) + call fseti (STDIMAGE, F_CANCEL, OK) + } + + # Get display parameters and set up transformation. + call ds_getparams (im, wdes, image, frame) + + # Erase the border (space between displayed image section and edge of + # window) only if screen was not erased and border erasing is enabled. + + if (frame_erase) + border_erase = false + else + border_erase = clgetb ("border_erase") + + # Display the image. + call ds_load_display (im, wdes, border_erase) + + call imunmap (im) + + # All done. + call gclose (gp) + call ids_close() + call sfree (sp) +end + + +# DS_GETPARAMS -- Get the parameters controlling how the image is mapped +# into the display frame. Set up the transformations and save in the graphics +# descriptor file. + +procedure ds_getparams (im, wdes, image, frame) + +pointer im, wdes # Image and graphics descriptors +char image[SZ_FNAME] # Should be determined from im +short frame[ARB] + +bool fill, zscale_flag, zrange_flag, zmap_flag +real xcenter, ycenter +real xsize, ysize, pxsize, pysize +real xmag, ymag, xscale, yscale +real z1, z2, contrast +int nsample_lines, ncols, nlines, len_stdline +pointer sp, w, ztrans, lut, lutfile + +bool clgetb() +int clgeti() +real clgetr() +bool streq() + +include "cv.com" + +begin + call smark (sp) + call salloc (ztrans, SZ_FNAME, TY_CHAR) + + # Set up a new graphics descriptor structure defining the coordinate + # transformation used to map the image into the display frame. + + call strcpy (image, W_IMSECT(wdes), W_SZIMSECT) + ncols = IM_LEN(im,1) + nlines = IM_LEN(im,2) + + # The fill, zscale, and zrange parameters determine the algorithms to + # be used to scale the image in the spatial and greyscale dimensions. + # If greyscale mapping is disabled the zscale and zrange options are + # disabled. Greyscale mapping can also be disabled by turning off + # zscale and zrange and setting Z1 and Z2 to the device greyscale min + # and max values, producing a unitary transformation. + + fill = clgetb ("fill") + call clgstr ("ztrans", Memc[ztrans], SZ_FNAME) + if (streq (Memc[ztrans], "none") || streq (Memc[ztrans], "user")) { + zscale_flag = false + zrange_flag = false + zmap_flag = false + } else { + zmap_flag = true + zscale_flag = clgetb ("zscale") + if (!zscale_flag) + zrange_flag = clgetb ("zrange") + } + + # Determine Z1 and Z2, the range of input greylevels to be mapped into + # the fixed range of display greylevels. + + if (zscale_flag) { + # Autoscaling is desired. Compute Z1 and Z2 which straddle the + # median computed by sampling a portion of the image. + + contrast = clgetr ("contrast") + nsample_lines = clgeti ("nsample_lines") + len_stdline = SAMPLE_SIZE / nsample_lines + call zscale (im, z1, z2, contrast, SAMPLE_SIZE, len_stdline) + + } else if (zrange_flag) { + nsample_lines = clgeti ("nsample_lines") + call maxmin (im, z1, z2, nsample_lines) + + } else if (zmap_flag) { + z1 = clgetr ("z1") + z2 = clgetr ("z2") + } + + # Determine the display window into which the image is to be mapped + # in normalized device coordinates. + + xcenter = max(0.0, min(1.0, clgetr ("xcenter"))) + ycenter = max(0.0, min(1.0, clgetr ("ycenter"))) + xsize = max(0.0, min(1.0, clgetr ("xsize"))) + ysize = max(0.0, min(1.0, clgetr ("ysize"))) + + # Determine X and Y scaling ratios required to map the image into the + # normalized display window. If spatial scaling is not desired filling + # must be disabled and XMAG and YMAG must be set to 1.0 in the + # parameter file. Fill mode will always produce an aspect ratio of 1; + # if nonequal scaling is required then the magnification ratios must + # be set explicitly by the user. + + if (fill) { + # Compute scale in units of window coords per data pixel required + # to scale image to fit window. + + xscale = xsize / max (1, (ncols - 1)) + yscale = ysize / max (1, (nlines - 1)) + + if (xscale < yscale) + yscale = xscale + else + xscale = yscale + + } else { + # Compute scale required to provide image magnification ratios + # specified by the user. Magnification is specified in units of + # display pixels, i.e, a magnification ratio of 1.0 means that + # image pixels will map to display pixels without scaling. + + xmag = clgetr ("xmag") + ymag = clgetr ("ymag") + xscale = 1.0 / ((cv_xres - 1) / xmag) + yscale = 1.0 / ((cv_yres - 1) / ymag) + } + + # Set device window limits in normalized device coordinates. + # World coord system 0 is used for the device window. + + w = W_WC(wdes,0) + W_XS(w) = xcenter - xsize / 2.0 + W_XE(w) = xcenter + xsize / 2.0 + W_YS(w) = ycenter - ysize / 2.0 + W_YE(w) = ycenter + ysize / 2.0 + + # Set pixel coordinates of window, world coordinate system #1. + + w = W_WC(wdes,1) + pxsize = xsize / xscale + pysize = ysize / yscale + + # If the image is too large to fit in the window given the scaling + # factors XSCALE and YSCALE, the following will set starting and ending + # pixel coordinates in the interior of the image. If the image is too + # small to fill the window then the pixel coords will reference beyond + # the bounds of the image. + + W_XS(w) = (ncols - 1) / 2.0 + 1 - (pxsize / 2.0) + W_XE(w) = W_XS(w) + pxsize + W_YS(w) = (nlines - 1) / 2.0 + 1 - (pysize / 2.0) + W_YE(w) = W_YS(w) + pysize + + # All spatial transformations are linear. + W_XT(w) = W_LINEAR + W_YT(w) = W_LINEAR + + # Determine whether a log or linear greyscale transformation is + # desired. + if (streq (Memc[ztrans], "log")) + W_ZT(w) = W_LOG + else if (streq (Memc[ztrans], "linear")) + W_ZT(w) = W_LINEAR + else if (streq (Memc[ztrans], "none")) + W_ZT(w) = W_UNITARY + else if (streq (Memc[ztrans], "user")) { + W_ZT(w) = W_USER + call salloc (lutfile, SZ_FNAME, TY_CHAR) + call clgstr ("lutfile", Memc[lutfile], SZ_FNAME) + call cv_ulut (Memc[lutfile], z1, z2, lut) + W_UPTR(w) = lut + } else { + call eprintf ("Bad greylevel transformation '%s'\n") + call pargstr (Memc[ztrans]) + W_ZT(w) = W_LINEAR + } + + # Set up the greyscale transformation. + W_ZS(w) = z1 + W_ZE(w) = z2 + + # Tell the user what values were used. + call printf ("cvl: z1 %6.1f, z2 %6.1f\n") + call pargr (z1) + call pargr (z2) + + # The user world coordinate system should be set from the CTRAN + # structure in the image header, but for now we just make it equal + # to the pixel coordinate system. + + call amovi (Memi[w], Memi[W_WC(wdes,2)], LEN_WC) +end diff --git a/pkg/images/tv/iis/src/load2.x b/pkg/images/tv/iis/src/load2.x new file mode 100644 index 00000000..5372907f --- /dev/null +++ b/pkg/images/tv/iis/src/load2.x @@ -0,0 +1,335 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +#### load2.x (from load.x) #### + +include <mach.h> +include <imset.h> +include <imhdr.h> +include <error.h> +include <gki.h> +include <fio.h> +include <fset.h> +include "gwindow.h" +include "../lib/ids.h" +include "cv.h" + +# DS_LOAD_DISPLAY -- Map an image into the display window. In general this +# involves independent linear transformations in the X, Y, and Z (greyscale) +# dimensions. If a spatial dimension is larger than the display window then +# the image is block averaged. If a spatial dimension or a block averaged +# dimension is smaller than the display window then linear interpolation is +# used to expand the image. Both the input image and the output device appear +# to us as images, accessed via IMIO. +# +# World coordinate system 0 (WCS 0) defines the position and size of the device +# window in NDC coordinates (0-1 in either axis). WCS 1 assigns a pixel +# coordinate system to the same window. If we convert the NDC coordinates of +# the window into device coordinates in pixels, then the ratios of the window +# coordinates in pixels to the image coordinates in pixels defines the real +# magnification factors for the two spatial axes. If the pixel coordinates +# are out of bounds then the image will be displayed centered in the window +# with zero fill at the edges. If the frame has not been erased then the fill +# areas must be explicitly zeroed. + +procedure ds_load_display (im, wdes, border_erase) + +pointer im # input image +pointer wdes # graphics window descriptor +bool border_erase + +int wx1, wx2, wy1, wy2 # device window to be filled with image data +real px1, px2, py1, py2 # image coords in fractional image pixels +real pxsize, pysize # size of image section in fractional pixels +real wxcenter, wycenter # center of device window in frac device pixels +real xmag, ymag # x,y magnification ratios +pointer w0, w1 # world coord systems 0 (NDC) and 1 (pixel) + +include "cv.com" + +begin + # Compute pointers to WCS 0 and 1. + w0 = W_WC(wdes,0) + w1 = W_WC(wdes,1) + + # Compute X and Y magnification ratios required to map image into + # the device window in device pixel units. + + xmag = (W_XE(w0) - W_XS(w0)) * cv_xres / (W_XE(w1) - W_XS(w1)) + ymag = (W_YE(w0) - W_YS(w0)) * cv_yres / (W_YE(w1) - W_YS(w1)) + + # Compute the coordinates of the image section to be displayed. + # This is not necessarily the same as WCS 1 since the WCS coords + # need not be inbounds. + + px1 = max (1.0, W_XS(w1)) + px2 = min (real (IM_LEN(im,1)), W_XE(w1)) + py1 = max (1.0, W_YS(w1)) + py2 = min (real (IM_LEN(im,2)), W_YE(w1)) + + # Now compute the coordinates of the image section to be written in + # device pixel units. This section must lie within or on the device + # window. + # This computation for I2S will give 257, which does differ by one + # for the Y center (due to inversion in I2S). This should not matter, + # but if it does, this comment will change! + + pxsize = px2 - px1 + pysize = py2 - py1 + wxcenter = (W_XE(w0) + W_XS(w0)) / 2.0 * cv_xres + 1 + wycenter = (W_YE(w0) + W_YS(w0)) / 2.0 * cv_yres + 1 + + wx1 = max (1, int (wxcenter - (pxsize / 2.0 * xmag))) + wx2 = max (wx1, min (cv_xres, int (wx1 + (pxsize * xmag)))) + wy1 = max (1, int (wycenter - (pysize / 2.0 * ymag))) + wy2 = max (wy1, min (cv_yres, int (wy1 + (pysize * ymag)))) + + # Display the image data, ignoring zero filling at the boundaries. + + call ds_map_image (im, px1,px2,py1,py2, wx1,wx2,wy1,wy2, + W_ZS(w1), W_ZE(w1), W_ZT(w1), W_UPTR(w1)) + + # Zero the border of the window if the frame has not been erased, + # and if the displayed section does not occupy the full window. + + if (border_erase) + call ds_erase_border (im, wdes, wx1,wx2,wy1,wy2) +end + + +# DS_MAP_IMAGE -- Map an image section from the input image to a section +# (window) of the output image (the display device). All spatial scaling is +# handled by the "scaled input" package, i.e., SIGL2[SR]. Our task is to +# get lines from the scaled input image, transform the greyscale if necessary, +# and write the lines to the output device. + +procedure ds_map_image (im, px1,px2,py1,py2, wx1,wx2,wy1,wy2, z1,z2,zt, uptr) + +pointer im # input image +real px1,px2,py1,py2 # input section +int wx1,wx2,wy1,wy2 # output section +real z1,z2 # range of input greylevels to be mapped. +int zt # log or linear greylevel transformation +pointer uptr # pointer to user transformation table + +bool unitary_greyscale_transformation +short lut1, lut2, z1_s, z2_s, dz1_s, dz2_s +real dz1, dz2 +int wy, nx, ny, xblk, yblk +pointer in, out, si +pointer sigl2s(), sigl2r(), sigl2_setup() +errchk sigl2s, sigl2r, sigl2_setup +real xs, xe, y +pointer sp, outr +bool fp_equalr() +real if_elogr() +extern if_elogr + +include "cv.com" + +begin + call smark (sp) + + # Set up for scaled image input. + + nx = wx2 - wx1 + 1 + ny = wy2 - wy1 + 1 + xblk = INDEFI + yblk = INDEFI + si = sigl2_setup (im, px1,px2,nx,xblk, py1,py2,ny,yblk) + + # Output array, and limiting x values in NDC + + call salloc (out, nx, TY_SHORT) + xs = real(wx1 - 1) * cv_xcon / GKI_MAXNDC + # Don't subtract 1 from wx2 as we want it to be first one not filled + xe = real(wx2) * cv_xcon / GKI_MAXNDC + if ( xe > 1.0) + xe = 1.0 + + # The device ZMIN and ZMAX parameters define the acceptable range + # of greyscale values for the output device (e.g., 0-255 for most 8-bit + # display devices). For the general display, we use 0 and the + # device "z" resolution. Values Z1 and Z2 are mapped linearly or + # logarithmically into these. + + dz1 = 0 + dz2 = cv_zres-1 + + # If the user specified the transfer function, see that the + # intensity and greyscale values are in range. + + if (zt == W_USER) { + call alims (Mems[uptr], SZ_BUF, lut1, lut2) + dz1_s = short (dz1) + dz2_s = short (dz2) + if (lut2 < dz1_s || lut1 > dz2_s) + call eprintf ("User specified greyscales out of range\n") + if (z2 < IM_MIN(im) || z1 > IM_MAX(im)) + call eprintf ("User specified intensities out of range\n") + } + + # Type short pixels are treated as a special case to minimize vector + # operations for such images (which are common). If the image pixels + # are either short or real then only the ALTR (greyscale transformation) + # vector operation is required. The ALTR operator linearly maps + # greylevels in the range Z1:Z2 to DZ1:DZ2, and does a floor ceiling + # of DZ1:DZ2 on all pixels outside the range. If unity mapping is + # employed the data is simply copied, i.e., floor ceiling constraints + # are not applied. This is very fast and will produce a contoured + # image on the display which will be adequate for some applications. + + if (zt == W_UNITARY) + unitary_greyscale_transformation = true + else + unitary_greyscale_transformation = + (fp_equalr (dz1,z1) && fp_equalr (dz2,z2)) || fp_equalr (z1,z2) + + if (IM_PIXTYPE(im) == TY_SHORT && zt != W_LOG) { + + # Set dz1_s and dz2_s depending on transformation + if (zt != W_USER) { + dz1_s = short (dz1) + dz2_s = short (dz2) + } else { + dz1_s = short (STARTPT) + dz2_s = short (ENDPT) + } + z1_s = short (z1) + z2_s = short (z2) + + for (wy=wy1; wy <= wy2; wy=wy+1) { + in = sigl2s (si, wy - wy1 + 1) + y = real(wy-1) * cv_ycon / GKI_MAXNDC + if (unitary_greyscale_transformation) + call gpcell (cv_gp, Mems[in], nx, 1, xs, y, xe, y) + else if (zt == W_USER) { + call amaps (Mems[in], Mems[out], nx, z1_s,z2_s, dz1_s,dz2_s) + call aluts (Mems[out], Mems[out], nx, Mems[uptr]) + call gpcell (cv_gp, Mems[out], nx, 1, xs, y, xe, y) + } else { + call amaps (Mems[in], Mems[out], nx, z1_s,z2_s, dz1_s,dz2_s) + call gpcell (cv_gp, Mems[out], nx, 1, xs, y, xe, y) + } + } + } else { + call salloc (outr, nx, TY_REAL) + for (wy=wy1; wy <= wy2; wy=wy+1) { + in = sigl2r (si, wy - wy1 + 1) + y = real(wy - 1) * cv_ycon / GKI_MAXNDC + + if (zt == W_LOG) { + call amapr (Memr[in], Memr[outr], nx, + z1, z2, 1.0, 10.0 ** MAXLOG) + call alogr (Memr[outr], Memr[outr], nx, if_elogr) + call amapr (Memr[outr], Memr[outr], nx, + 1.0, real(MAXLOG), dz1, dz2) + call achtrs (Memr[outr], Mems[out], nx) + } else if (unitary_greyscale_transformation) { + call achtrs (Memr[in], Mems[out], nx) + } else if (zt == W_USER) { + call amapr (Memr[in], Memr[outr], nx, z1,z2, STARTPT,ENDPT) + call achtrs (Memr[outr], Mems[out], nx) + call aluts (Mems[out], Mems[out], nx, Mems[uptr]) + } else { + call amapr (Memr[in], Memr[outr], nx, z1, z2, dz1, dz2) + call achtrs (Memr[outr], Mems[out], nx) + } + call gpcell (cv_gp, Mems[out], nx, 1, xs, y, xe, y) + } + } + + call sfree (sp) + call sigl2_free (si) +end + + +# DS_ERASE_BORDER -- Zero the border of the window if the frame has not been +# erased, and if the displayed section does not occupy the full window. +# It would be more efficient to do this while writing the greyscale data to +# the output image, but that would complicate the display procedures and frames +# are commonly erased before displaying an image. + +procedure ds_erase_border (im, wdes, wx1,wx2,wy1,wy2) + +pointer im # input image +pointer wdes # window descriptor +int wx1,wx2,wy1,wy2 # section of display window filled by image data + +int dx1,dx2,dy1,dy2 # coords of full display window in device pixels +int j, n, n1 +pointer w0 +pointer sp, zero +real xls, xle, xrs, xre, y + +include "cv.com" + +begin + call smark (sp) + call salloc (zero, cv_xres, TY_SHORT) + call aclrs (Mems[zero], cv_xres) + + # Compute device pixel coordinates of the full display window. + w0 = W_WC(wdes,0) + dx1 = W_XS(w0) * (cv_xres - 1) + 1 + dx2 = W_XE(w0) * (cv_xres - 1) + 1 + dy1 = W_YS(w0) * (cv_yres - 1) + 1 + dy2 = W_YE(w0) * (cv_yres - 1) + 1 + + # Determine left and right (exclusive), start and end, x values in NDC + # for pixels not already filled. + # If, say, dx1 < wx1, we want to clear dx1 through wx1-1, which means + # that for gpcell, we want the (right) end points to be the first + # pixel not cleared. + xls = real(dx1 - 1) * cv_xcon / GKI_MAXNDC + xle = real(wx1) * cv_xcon / GKI_MAXNDC + if (xle > 1.0) + xle = 1.0 + xre = real(dx2 - 1) * cv_xcon / GKI_MAXNDC + xrs = real(wx2) * cv_xcon / GKI_MAXNDC + if (xre > 1.0) + xre = 1.0 + + # Erase lower margin. + n = dx2 - dx1 + 1 + for (j=dy1; j < wy1; j=j+1) { + y = real(j-1) * cv_ycon / GKI_MAXNDC + call gpcell (cv_gp, Mems[zero], n, 1, xls, y, xre, y) + } + + # Erase left and right margins. By doing the right margin of a line + # immediately after the left margin we have a high liklihood that the + # display line will still be in the FIO buffer. + + n = wx1 - dx1 + n1 = dx2 - wx2 + for (j=wy1; j <= wy2; j=j+1) { + y = real(j-1) * cv_ycon / GKI_MAXNDC + if (dx1 < wx1) + call gpcell (cv_gp, Mems[zero], n, 1, xls, y, xle, y) + if (wx2 < dx2) + call gpcell (cv_gp, Mems[zero], n1, 1, xrs, y, xre, y) + } + + # Erase upper margin. + n = dx2 - dx1 + 1 + for (j=wy2+1; j <= dy2; j=j+1) { + y = real(j-1) * cv_ycon / GKI_MAXNDC + call gpcell (cv_gp, Mems[zero], n, 1, xls, y, xre, y) + } + + call sfree (sp) +end + + +# IF_ELOG -- The error function for log10. Note that MAX_EXPONENT is +# currently an integer so it is converted to the appropriate data type +# before being returned. + +real procedure if_elogr (x) + +real x # the input pixel value + +begin + return (real(-MAX_EXPONENT)) +end + diff --git a/pkg/images/tv/iis/src/map.x b/pkg/images/tv/iis/src/map.x new file mode 100644 index 00000000..5ea7c230 --- /dev/null +++ b/pkg/images/tv/iis/src/map.x @@ -0,0 +1,320 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctotok.h> +include <ctype.h> +include <gki.h> +include "../lib/ids.h" + +# MAP -- set fixed or variable LUT mapping + +procedure map(command) + +char command[ARB] + +char token[SZ_LINE] +int tok +short frames[IDS_MAXIMPL+2] # frames, graphics, EOD +short colors[IDS_MAXGCOLOR] +int device +short pcolor[2] +real limit +long seed +real urand(), xfactor +int ctoi() +int i, ip, iseed, level, nchar +bool triangle +pointer sp, rdata, gdata, bdata, rp, gp, bp + +include "cv.com" + +begin + # Find out if want to change output tables + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + if (( tok == TOK_IDENTIFIER) && (token[1] == 'o' )) { + device = IDS_OUTPUT_LUT + } else { + device = IDS_FRAME_LUT + # reset input pointers; same as having pushed back token + call reset_scan + call gargtok (tok, token, SZ_LINE) + } + + # Default to all frames, all colors + frames[1] = IDS_EOD + colors[1] = IDS_EOD + triangle = true # default to simple three function type + seed = -1 + level = 8 + + # which frames to change, colors, etc + + repeat { + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + if (tok == TOK_IDENTIFIER) { + if (token[1] == 'f') { + call cv_frame (token[2], frames) + if (frames[1] == ERR) + return + } else if (token[1] == 'c') { + call cv_color (token[2], colors) + if (colors[1] == ERR) + return + } else if (token[1] == 'r') { # (random) level count + ip = 2 + nchar = ctoi (token, ip, level) + if (nchar <= 0) { + call eprintf ("Incorrect random count: %s\n") + call pargstr (token[2]) + return + } + if (level < 4) + level = 4 + else if (level > 128) + level = 128 + triangle = false + } else if (token[1] == 's') { # seed + ip = 2 + nchar = ctoi (token, ip, iseed) + if (nchar <= 0) { + call eprintf ("Incorrect seed: %s\n") + call pargstr (token[2]) + return + } + seed = iseed + triangle = false + } else { + call eprintf ("Unknown map argument: %s\n") + call pargstr (token) + return + } + } else if (tok != TOK_NEWLINE) { + call eprintf ("Unexpected map input: %s\n") + call pargstr (token) + return + } + } until ( tok == TOK_NEWLINE) + + pcolor[2] = IDS_EOD + # Sorry, but we "know" that ofm shouldn't go beyond first + # 256 for common NOAO use. + if ( device == IDS_FRAME_LUT) + limit = 1.0 + else + limit = 0.25 + + # Build the three functions and load them. + # First, expand colors if using all + + if (colors[1] == IDS_EOD) { + colors[1] = IDS_RED + colors[2] = IDS_GREEN + colors[3] = IDS_BLUE + colors[4] = IDS_EOD + } + + # if standard pseudocolor, let kodak do it + + if (triangle) { + call kodak (device, frames, colors, limit) + return + } + + # Not standard pseudo color -- do random one + # First, set up arrays + + call smark (sp) + call salloc (rdata, level*4, TY_SHORT) + call salloc (gdata, level*4, TY_SHORT) + call salloc (bdata, level*4, TY_SHORT) + + if (seed == -1) + seed = level + + call aclrs (Mems[rdata], level*4) + call aclrs (Mems[gdata], level*4) + call aclrs (Mems[bdata], level*4) + + xfactor = real(GKI_MAXNDC)/level * limit + + # set first data points to zero (0,0) to (1/level,0) + Mems[rdata+2] = xfactor + Mems[gdata+2] = xfactor + Mems[bdata+2] = xfactor + # Set last segment to white ((level-1)/level,1.0) to (1.0,1.0) + Mems[rdata+level*4-4] = real(level-1) * xfactor + Mems[gdata+level*4-4] = real(level-1) * xfactor + Mems[bdata+level*4-4] = real(level-1) * xfactor + Mems[rdata+level*4-3] = GKI_MAXNDC + Mems[gdata+level*4-3] = GKI_MAXNDC + Mems[bdata+level*4-3] = GKI_MAXNDC + Mems[rdata+level*4-2] = GKI_MAXNDC + Mems[gdata+level*4-2] = GKI_MAXNDC + Mems[bdata+level*4-2] = GKI_MAXNDC + Mems[rdata+level*4-1] = GKI_MAXNDC + Mems[gdata+level*4-1] = GKI_MAXNDC + Mems[bdata+level*4-1] = GKI_MAXNDC + + # Do the intermediate ones + do i=2, level-1 { + rp = rdata + (i-1)*4 + gp = gdata + (i-1)*4 + bp = bdata + (i-1)*4 + Mems[rp] = real(i-1) * xfactor + Mems[gp] = real(i-1) * xfactor + Mems[bp] = real(i-1) * xfactor + Mems[rp+1] = urand(seed) * GKI_MAXNDC + Mems[gp+1] = urand(seed) * GKI_MAXNDC + Mems[bp+1] = urand(seed) * GKI_MAXNDC + Mems[rp+2] = real(i) * xfactor + Mems[gp+2] = real(i) * xfactor + Mems[bp+2] = real(i) * xfactor + Mems[rp+3] = Mems[rp+1] + Mems[gp+3] = Mems[gp+1] + Mems[bp+3] = Mems[bp+1] + } + + # If color requested, do it + for ( i = 1; colors[i] != IDS_EOD; i = i + 1 ) { + pcolor[1] = colors[i] + switch (colors[i]) { + case IDS_RED: + call cvwlut (device, frames, pcolor, Mems[rdata], level*4) + + case IDS_GREEN: + call cvwlut (device, frames, pcolor, Mems[gdata], level*4) + + case IDS_BLUE: + call cvwlut (device, frames, pcolor, Mems[bdata], level*4) + } + } + + call sfree (sp) +end + +# KODAK -- provides three variable width and variable center triangular +# color mapping functions. + +procedure kodak (device, frames, colors, limit) + +int device # IDS_FRAME_LUT or IDS_OUTPUT_LUT +short frames[ARB] # frames to change +short colors[ARB] # colors to affect +real limit # factor to apply to limit x range + +short wdata[20], pcolor[2] +real center, width +int n, ksub(), button, i +int cv_rdbut(), cv_wtbut() + +begin + pcolor[2] = IDS_EOD + for (i = 1; colors[i] != IDS_EOD; i = i + 1) { + pcolor[1] = colors[i] + switch (colors[i]) { + case IDS_RED: + n = ksub (1.0, 0.5, wdata, limit) + + case IDS_GREEN: + n = ksub (0.5, 0.5, wdata, limit) + + case IDS_BLUE: + n = ksub (0.0, 0.5, wdata, limit) + } + + call cvwlut (device, frames, pcolor, wdata, n) + } + + button = cv_rdbut() # clear buttons + repeat { + call eprintf ("Press A, B, C for red, green, blue; D to exit\n") + button = cv_wtbut() + if (button == 4) + break + switch (button) { + case 1: + pcolor[1] = IDS_RED + + case 2: + pcolor[1] = IDS_GREEN + + case 3: + pcolor[1] = IDS_BLUE + } + + # Loop, reading cursor and modifying the display for the + # selected color. + + repeat { + call cv_rcraw(center, width) + width = width * 2. # flatten it + n = ksub (center, width, wdata, limit) + call cvwlut (device, frames, pcolor, wdata, n) + button = cv_rdbut() + } until (button != 0) + } +end + +# KSUB -- determines data points for a triangular mapping function +# Returns number of points in data array. + +int procedure ksub (center, width, data, limit) + +real center, width, limit +short data[ARB] + +int n +real xs, xe, ys, ye, xscale + +include "cv.com" + +begin + n = 0 + xscale = GKI_MAXNDC * limit + if (width < (1.0/cv_yres)) + width = 1.0/cv_yres + + if (center > 0.) { + xs = center - width + if (xs < 0.) + xs = 0. + else if (xs > 0.) { + data[1] = 0. + data[2] = 0. + n = n + 2 + } + ys = (xs - center)/width + 1.0 + data[n+1] = xs * xscale + data[n+2] = ys * GKI_MAXNDC + data[n+3] = center * xscale + data[n+4] = GKI_MAXNDC + n = n + 4 + } + + if (center < 1.0) { + xe = width + center + if (xe > 1.0) + xe = 1.0 + ye = (center - xe)/width + 1.0 + data[n+1] = center * xscale + data[n+2] = GKI_MAXNDC + data[n+3] = xe * xscale + data[n+4] = ye * GKI_MAXNDC + n = n + 4 + if (xe < 1.0) { + data[n+1] = xscale + data[n+2] = 0 + n = n + 2 + } + } + + # Extend last value to end + if (limit != 1.0) { + data[n+1] = GKI_MAXNDC + data[n+2] = data[n] + n = n + 2 + } + + return (n) +end diff --git a/pkg/images/tv/iis/src/match.x b/pkg/images/tv/iis/src/match.x new file mode 100644 index 00000000..ebbe523d --- /dev/null +++ b/pkg/images/tv/iis/src/match.x @@ -0,0 +1,172 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctotok.h> +include "../lib/ids.h" + +# MATCH -- Match look up tables. The command reads +# match this_one (to) that one + +procedure match + +char token[SZ_LINE] +int tok +short f_ref[2] +short c_ref[IDS_MAXGCOLOR+1] +short frames[IDS_MAXIMPL+1] +short colors[IDS_MAXGCOLOR+1] +short nextcolor +int nchar, i, val, ctoi() +int ltype + +include "cv.com" + +begin + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + if ( (tok == TOK_IDENTIFIER) && (token[1] == 'o') ) { + ltype = IDS_OUTPUT_LUT + } else { + ltype = IDS_FRAME_LUT + # "Push back" the token + call reset_scan + call gargtok (tok, token, SZ_LINE) + } + + # All this parsing tells us why YACC and LEX were invented + # Use "i" to tell if have parsed something useful + + i = -1 + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + if ((tok == TOK_IDENTIFIER) && (token[1] == 'f')) { + i = 1 + call cv_frame (token[2], frames) + if (frames[1] == ERR) + return + } else if (tok == TOK_NUMBER) { + i = 1 + nchar = ctoi (token, i, val) + if ((val < 1) || (val > cv_maxframes)) { + call eprintf ("Invalid frame specification: %d\n") + call pargi (val) + return + } else { + frames[1] = val + frames[2] = IDS_EOD + } + } else if (ltype == IDS_FRAME_LUT) { + call eprintf ("missing frame arguement\n") + return + } else + frames[1] = IDS_EOD + + # default first color argument to all colors for both FRAME and OUTPUT + # tables...means make all colors the same. + + colors[1] = IDS_EOD # default all colors + + # Advance if previous token was useful + + if ( i != -1 ) { + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + } + + # Look for a color + + if ((tok == TOK_IDENTIFIER) && (token[1] == 'c')) { + call cv_color (token[2], colors) + if (colors[1] == ERR) + return + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + } + + # look for fill word "to" + + if ((tok == TOK_IDENTIFIER) && (token[1] == 't')) { + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + } + + # if FRAME LUT, we default frame to first frame to be changed. + # if OUTPUT LUT, frame is irrelevant + + i = -1 + if (tok == TOK_IDENTIFIER) { + if (token[1] == 'f') + i = 2 + else if (token[1] != 'c') { + call eprintf ("Unexpected argument: %s\n") + call pargstr (token) + return + } + } else if (tok == TOK_NUMBER) + i = 1 + + # if ltype is OUTPUT lut, don't care about frame type, but can't + # omit it...so default to EOD + + f_ref[1] = IDS_EOD + f_ref[2] = IDS_EOD + if (ltype == IDS_FRAME_LUT) { + if (i == -1) { + f_ref[1] = frames[1] + } else { + nchar = ctoi (token, i, val) + if ((val < 1) || (val > cv_maxframes)) { + call eprintf ("Invalid frame specification: %d\n") + call pargi (val) + return + } + f_ref[1] = val + } + } + + # Only thing left should be the reference color. + # If found a frame before, advance the token. + + if (i != -1) { + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + } + if ((tok != TOK_NEWLINE) && (tok != TOK_IDENTIFIER)) { + call eprintf ("Unexpected input: %s\n") + call pargstr (token) + return + } + c_ref[1] = IDS_EOD + if (tok == TOK_IDENTIFIER) { + if (token[1] != 'c') { + call eprintf ("Unexpected input (color required): %s\n") + call pargstr (token) + return + } else { + call cv_color (token[2], c_ref) + if (c_ref[1] == ERR) + return + } + } + + if (c_ref[1] != IDS_EOD) + call cvmatch (ltype, f_ref, c_ref, frames, colors) + else { + # No specific color for reference. If no color specified + # to copy into, do all. + c_ref[2] = IDS_EOD + if ( colors[1] == IDS_EOD ) { + colors[1] = IDS_RED + colors[2] = IDS_GREEN + colors[3] = IDS_BLUE + colors[4] = IDS_EOD + } + # Match for each color given in "colors" + for ( i = 1 ; colors[i] != IDS_EOD; i = i + 1) { + nextcolor = colors[i+1] + colors[i+1] = IDS_EOD + c_ref[1] = colors[i] + call cvmatch (ltype, f_ref, c_ref, frames, colors[i]) + colors[i+1] = nextcolor + } + } +end diff --git a/pkg/images/tv/iis/src/maxmin.x b/pkg/images/tv/iis/src/maxmin.x new file mode 100644 index 00000000..d16874e9 --- /dev/null +++ b/pkg/images/tv/iis/src/maxmin.x @@ -0,0 +1,52 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <mach.h> +include <imhdr.h> + +# MAXMIN -- Get the minimum and maximum pixel values of an image. If valid +# header values are available they are used, otherwise the image is sampled +# on an even grid and the min and max values of this sample are returned. + +procedure maxmin (im, zmin, zmax, nsample_lines) + +pointer im +real zmin, zmax # min and max intensity values +int nsample_lines # amount of image to sample + +int step, ncols, nlines, sample_size, imlines, i +real minval, maxval +pointer imgl2r() + +begin + # Only calculate minimum, maximum pixel values if the current + # values are unknown, or if the image was modified since the + # old values were computed. + + ncols = IM_LEN(im,1) + nlines = IM_LEN(im,2) + + if (IM_LIMTIME(im) >= IM_MTIME(im)) { + # Use min and max values in image header if they are up to date. + zmin = IM_MIN(im) + zmax = IM_MAX(im) + + } else { + zmin = MAX_REAL + zmax = -MAX_REAL + + # Try to include a constant number of pixels in the sample + # regardless of the image size. The entire image is used if we + # have a small image, and at least sample_lines lines are read + # if we have a large image. + + sample_size = 512 * nsample_lines + imlines = min(nlines, max(nsample_lines, sample_size / ncols)) + step = nlines / (imlines + 1) + + do i = 1 + step, nlines, max (1, step) { + call alimr (Memr[imgl2r(im,i)], ncols, minval, maxval) + zmin = min (zmin, minval) + zmax = max (zmax, maxval) + } + } +end diff --git a/pkg/images/tv/iis/src/mkpkg b/pkg/images/tv/iis/src/mkpkg new file mode 100644 index 00000000..34ee515c --- /dev/null +++ b/pkg/images/tv/iis/src/mkpkg @@ -0,0 +1,39 @@ +# Make the CV display load and control package. + +$checkout libpkg.a ../ +$update libpkg.a +$checkin libpkg.a ../ +$exit + +libpkg.a: + blink.x ../lib/ids.h <ctotok.h> <ctype.h> <gki.h> cv.com + clear.x ../lib/ids.h <ctotok.h> <ctype.h> cv.com + cv.x cv.com cv.h ../lib/ids.h <ctotok.h> <error.h> <fio.h>\ + <fset.h> <gki.h> + cvparse.x cv.com ../lib/ids.h <ctype.h> + cvulut.x cv.h <ctype.h> <error.h> + cvutil.x cv.com cv.h ../lib/ids.h <gki.h> <gset.h> <imhdr.h>\ + cv.com + display.x ../lib/ids.h <ctotok.h> <ctype.h> cv.com + load1.x cv.com cv.h ../lib/ids.h <error.h> <gki.h> gwindow.h\ + <fio.h> <fset.h> <imhdr.h> <imset.h> <mach.h> + load2.x cv.com cv.h ../lib/ids.h <error.h> <gki.h> gwindow.h\ + cv.com <fio.h> <fset.h> <imhdr.h> <imset.h> <mach.h> + map.x ../lib/ids.h <ctotok.h> <ctype.h> <gki.h> cv.com + match.x ../lib/ids.h <ctotok.h> cv.com + maxmin.x <imhdr.h> <mach.h> + offset.x ../lib/ids.h <ctotok.h> <ctype.h> cv.com + pan.x cv.com ../lib/ids.h <ctotok.h> <ctype.h> <gki.h> + range.x ../lib/ids.h <ctotok.h> <ctype.h> cv.com + rdcur.x ../lib/ids.h <ctotok.h> <ctype.h> cv.com <gki.h> + reset.x ../lib/ids.h <ctotok.h> <ctype.h> cv.com + sigl2.x <error.h> <imhdr.h> + snap.x ../lib/ids.h <ctotok.h> <ctype.h> cv.com <gki.h>\ + <imhdr.h> + split.x ../lib/ids.h <ctotok.h> <ctype.h> cv.com + tell.x ../lib/ids.h cv.com + text.x ../lib/ids.h <ctotok.h> <ctype.h> + window.x ../lib/ids.h <ctotok.h> <ctype.h> <gki.h> cv.com + zoom.x ../lib/ids.h <ctotok.h> <ctype.h> <gki.h> cv.com + zscale.x <imhdr.h> + ; diff --git a/pkg/images/tv/iis/src/offset.x b/pkg/images/tv/iis/src/offset.x new file mode 100644 index 00000000..356ae55f --- /dev/null +++ b/pkg/images/tv/iis/src/offset.x @@ -0,0 +1,53 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctotok.h> +include <ctype.h> +include "../lib/ids.h" + +# OFFSET -- Change the bias (offset) for certain colors + +procedure offset() + +int tok, i, nchar, ip +char token[SZ_LINE] +short color[IDS_MAXGCOLOR+1] +short offsetdata[4] # extra space for cvmove EOD +int count, ctoi() + +include "cv.com" + +begin + # In principle, we should be able to accept input for color group + # followed by offset value(s) or "vice versa" or for a series of + # color/offset pairs. We try for most of that. + color[1] = ERR + offsetdata[1] = ERR + count = 1 + # anything but TOK_NEWLINE + tok = TOK_NUMBER + repeat { + if (tok == TOK_NEWLINE) { + call eprintf ("Insufficient offset specification\n") + return + } + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + if (token[1] == 'c') { + call cv_color (token[2], color) + if (color[1] == ERR) + return + } else if (tok == TOK_NUMBER) { + ip = 1 + nchar = ctoi (token, ip, i) + if ( count <= 3) { + offsetdata[count] = i + count = count + 1 + } + } + } until ( (color[1] != ERR) && (offsetdata[1] != ERR) && + (tok == TOK_NEWLINE) ) + + offsetdata[count] = IDS_EOD # mark end + + call cvoffset (color, offsetdata) +end diff --git a/pkg/images/tv/iis/src/pan.x b/pkg/images/tv/iis/src/pan.x new file mode 100644 index 00000000..b8929510 --- /dev/null +++ b/pkg/images/tv/iis/src/pan.x @@ -0,0 +1,99 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctotok.h> +include <ctype.h> +include <gki.h> +include "../lib/ids.h" + +# PAN -- pan some or all of the frames + +procedure pan() + +char token[SZ_LINE] +int tok +short frames[IDS_MAXIMPL+2] # frames, graphics, EOD + +include "cv.com" + +begin + frames[1] = IDS_EOD # default all frames + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + if (token[1] == 'f') { + call cv_frame (token[2], frames) + if (frames[1] == ERR) + return + } else if (tok == TOK_NUMBER) { + call cv_frame (token[1], frames) + if (frames[1] == ERR) + return + } else { + call eprintf ("Unexpected input: %s\n") + call pargstr (token) + return + } + + call pansub (frames) +end + + +# PANSUB -- Pan subroutine, handles code common to pan and zoom + +procedure pansub (frames) + +short frames[ARB] # frames to pan + +int button +int cnum, cv_rdbut() +real x,y, xc, yc +real oldx, oldy + +include "cv.com" + +begin + button = cv_rdbut() # clear buttons by reading them + call eprintf ("Press any button when done\n") + + # Where is cursor now? + + call cv_rcraw (xc,yc) + + # Calculate NDC screen center and cursor number. + # x,y are NDC, but always < 1.0 The transformation applied here + # insures that the correct pixel is calculated by the kernel + # after passing x,y through the gio cursor routines. + x = real(cv_xcen - 1) * cv_xcon / GKI_MAXNDC + y = real(cv_ycen - 1) * cv_ycon / GKI_MAXNDC + cnum = frames[1] + if (cnum == IDS_EOD) + cnum = 0 + call cv_scraw (x, y) # put cursor at screen center + + # Determine NDC there for frame of interest + call cv_rcur (cnum, x, y) + + # Restore cursor + call cv_scraw (xc, yc) + + repeat { + oldx = xc + oldy = yc + repeat { + call cv_rcraw (xc, yc) + button = cv_rdbut() + } until ( (xc != oldx) || (yc != oldy) || (button > 0)) + # Determine change and reflect it about current screen + # center so image moves in direction cursor moves. + x = x - (xc - oldx) + y = y - (yc - oldy) + if (x > 1.0) + x = x - 1.0 + else if (x < 0) + x = x + 1.0 + if (y > 1.0) + y = y - 1.0 + else if (y < 0) + y = y + 1.0 + call cvpan (frames, x, y) + } until (button > 0) +end diff --git a/pkg/images/tv/iis/src/range.x b/pkg/images/tv/iis/src/range.x new file mode 100644 index 00000000..664e3ab8 --- /dev/null +++ b/pkg/images/tv/iis/src/range.x @@ -0,0 +1,57 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctotok.h> +include <ctype.h> +include "../lib/ids.h" + +# RANGE -- set the scaling (range) registers + +procedure range() + +char token[SZ_LINE] +int tok, i, nchar, ip +short color[IDS_MAXGCOLOR+1] +short rdata[4] # extra space for cvmove EOD +int count, ctoi() + +include "cv.com" + +begin + # In principle, we should be able to accept input for color group + # followed by range value(s) or "vice versa" or for a series of + # color/range pairs. We try for most of that. + color[1] = IDS_EOD + rdata[1] = ERR + count = 1 + # anything but TOK_NEWLINE + tok = TOK_NUMBER + repeat { + if (tok == TOK_NEWLINE) { + call eprintf ("Insufficient range specification\n") + return + } + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + if (token[1] == 'c') { + call cv_color (token[2], color) + if (color[1] == ERR) + return + } else if (tok == TOK_NUMBER) { + ip = 1 + nchar = ctoi (token, ip, i) + if (i < 1) { + call eprintf ("bad range specification: %d\n") + call pargi (i) + return + } + if ( count <= 3) { + rdata[count] = i + count = count + 1 + } + } + } until ( (rdata[1] != ERR) && (tok == TOK_NEWLINE )) + + rdata[count] = IDS_EOD # mark end + + call cvrange ( color, rdata) +end diff --git a/pkg/images/tv/iis/src/rdcur.x b/pkg/images/tv/iis/src/rdcur.x new file mode 100644 index 00000000..5d27097e --- /dev/null +++ b/pkg/images/tv/iis/src/rdcur.x @@ -0,0 +1,111 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctotok.h> +include <ctype.h> +include <gki.h> +include "../lib/ids.h" + +# RDCUR -- read cursor and datum + +procedure rdcur() + +char token[SZ_LINE], ch +int tok, cnum, px, py +int junk, ip, fx, fy +real x,y +short datum +short frames[IDS_MAXIMPL+2] # frames, one graphics, EOD +int scan(), ctoi(), mod(), and() + +include "cv.com" + +begin + cnum = ERR + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + if (tok == TOK_NUMBER) { + ip = 1 + junk = ctoi (token, ip, cnum) + frames[1] = cnum + frames[2] = IDS_EOD + } + else if (tok == TOK_IDENTIFIER) { + if (token[1] == 'o') { + if (token[2] == 'n') + call cvcur(IDS_ON) + else if (token[2] == 'f') + call cvcur(IDS_OFF) + else { + call eprintf ("Unrecognized cursor command: %s\n") + call pargstr (token) + } + return + } + call cv_frame (token[2], frames) + cnum = frames[1] + if ( cnum == IDS_EOD) { + call eprintf ("Please specify a particular frame\n") + return + } + } + if ( (cnum == ERR) || (cnum < 1) ) { + call eprintf ("bad cursor number: %d\n") + call pargi (cnum) + return + } + + # set kernel to do i/o on specified frames (for ggcell routine) + call cv_iset (frames) + + call eprintf ("Press <cr> for each read; any key but <sp>, and then <cr>, to exit\n") + repeat { + if (scan() != EOS) + break + repeat { + call scanc (ch) + } until (ch != ' ') + if (ch != '\n') + break + call cv_rcur (cnum, x, y) + call ggcell (cv_gp, datum, 1, 1, x, y, x, y) + x = x * GKI_MAXNDC / cv_xcon + 1. + y = y * GKI_MAXNDC / cv_ycon + 1. + px = int(x) + py = int(y) + # Only allow fractions to 1/8 as that is max zoom for IIS + x = real (int((x - px)*8))/8. + y = real (int((y - py)*8))/8. + # Print minimum number of decimal places, but do x and y the same + call eprintf ("frame %d, pixel (") + call pargi (cnum) + fx = x * 8 + fy = y * 8 + if ((fx == 0) && (fy == 0)) { + call eprintf ("%d,%d") + call pargi (px) + call pargi (py) + junk = 0 + } else { + call eprintf ("%.*f,%.*f") + + if ( (mod(fx,4) == 0) && (mod(fy,4) == 0) ) + junk = 1 + else if ( (and(fx,1) != 0) || (and(fy,1) != 0) ) + junk = 3 + else + junk = 2 + + call pargi (junk) + call pargr (px+x) + call pargi (junk) + call pargr (py+y) + } + if (junk == 0) + junk = 8 + else + junk = 6 - 2 * junk + call eprintf ("): %*w%4d\n") + call pargi (junk) + call pargs (datum) + } +end diff --git a/pkg/images/tv/iis/src/reset.x b/pkg/images/tv/iis/src/reset.x new file mode 100644 index 00000000..3a2e60e9 --- /dev/null +++ b/pkg/images/tv/iis/src/reset.x @@ -0,0 +1,37 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctotok.h> +include <ctype.h> +include "../lib/ids.h" + +# RESET -- reset the display + +procedure reset() + +char token[SZ_LINE] +int tok + +include "cv.com" + +begin + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + if (tok == TOK_IDENTIFIER) { + switch(token[1]) { + case 'r': + call cvreset( IDS_R_SOFT) + + case 't': + call cvreset( IDS_R_MEDIUM) + + case 'i': + call cvreset( IDS_R_HARD) + + case 'a': + call cvreset( IDS_R_SOFT) + call cvreset( IDS_R_MEDIUM) + call cvreset( IDS_R_HARD) + + } + } +end diff --git a/pkg/images/tv/iis/src/sigl2.x b/pkg/images/tv/iis/src/sigl2.x new file mode 100644 index 00000000..226d4f5b --- /dev/null +++ b/pkg/images/tv/iis/src/sigl2.x @@ -0,0 +1,677 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> +include <error.h> + +.help sigl2, sigl2_setup +.nf ___________________________________________________________________________ +SIGL2 -- Get a line from a spatially scaled 2-dimensional image. This procedure +works like the regular IMIO get line procedure, but rescales the input +2-dimensional image in either or both axes upon input. If the magnification +ratio required is greater than 0 and less than 2 then linear interpolation is +used to resample the image. If the magnification ratio is greater than or +equal to 2 then the image is block averaged by the smallest factor which +reduces the magnification to the range 0-2 and then interpolated back up to +the desired size. In some cases this will smooth the data slightly, but the +operation is efficient and avoids aliasing effects. + + si = sigl2_setup (im, x1,x2,nx, y1,y2,ny) + sigl2_free (si) + ptr = sigl2[sr] (si, linenumber) + +SIGL2_SETUP must be called to set up the transformations after mapping the +image and before performing any scaled i/o to the image. SIGL2_FREE must be +called when finished to return buffer space. +.endhelp ______________________________________________________________________ + +# Scaled image descriptor for 2-dim images + +define SI_LEN 15 +define SI_MAXDIM 2 # images of 2 dimensions supported +define SI_NBUFS 3 # nbuffers used by SIGL2 + +define SI_IM Memi[$1] # pointer to input image header +define SI_GRID Memi[$1+1+$2-1] # pointer to array of X coords +define SI_NPIX Memi[$1+3+$2-1] # number of X coords +define SI_BAVG Memi[$1+5+$2-1] # X block averaging factor +define SI_INTERP Memi[$1+7+$2-1] # interpolate X axis +define SI_BUF Memi[$1+9+$2-1] # line buffers +define SI_TYBUF Memi[$1+12] # buffer type +define SI_XOFF Memi[$1+13] # offset in input image to first X +define SI_INIT Memi[$1+14] # YES until first i/o is done + +define OUTBUF SI_BUF($1,3) + +define SI_TOL (1E-5) # close to a pixel +define INTVAL (abs ($1 - nint($1)) < SI_TOL) +define SWAPI {tempi=$2;$2=$1;$1=tempi} +define SWAPP {tempp=$2;$2=$1;$1=tempp} +define NOTSET (-9999) + +# SIGL2_SETUP -- Set up the spatial transformation for SIGL2[SR]. Compute +# the block averaging factors (1 if no block averaging is required) and +# the sampling grid points, i.e., pixel coordinates of the output pixels in +# the input image. +# +# Valdes - Jan 9, 1985: +# Nx or ny can be 1 and blocking factors can be specified. + +pointer procedure sigl2_setup (im, px1, px2, nx, xblk, py1, py2, ny, yblk) + +pointer im # the input image +real px1, px2 # range in X to be sampled on an even grid +int nx # number of output pixels in X +int xblk # blocking factor in x +real py1, py2 # range in Y to be sampled on an even grid +int ny # number of output pixels in Y +int yblk # blocking factor in y + +int npix, noldpix, nbavpix, i, j +int npts[SI_MAXDIM] # number of output points for axis +int blksize[SI_MAXDIM] # block averaging factor (npix per block) +real tau[SI_MAXDIM] # tau = p(i+1) - p(i) in fractional pixels +real p1[SI_MAXDIM] # starting pixel coords in each axis +real p2[SI_MAXDIM] # ending pixel coords in each axis +real scalar, start +pointer si, gp + +begin + iferr (call calloc (si, SI_LEN, TY_STRUCT)) + call erract (EA_FATAL) + + SI_IM(si) = im + SI_NPIX(si,1) = nx + SI_NPIX(si,2) = ny + SI_INIT(si) = YES + + p1[1] = px1 # X = index 1 + p2[1] = px2 + npts[1] = nx + blksize[1] = xblk + + p1[2] = py1 # Y = index 2 + p2[2] = py2 + npts[2] = ny + blksize[2] = yblk + + # Compute block averaging factors if not defined. + # If there is only one pixel then the block average is the average + # between the first and last point. + + do i = 1, SI_MAXDIM { + if ((blksize[i] >= 1) && !IS_INDEFI (blksize[i])) { + if (npts[i] == 1) + tau[i] = 0. + else + tau[i] = (p2[i] - p1[i]) / (npts[i] - 1) + } else { + if (npts[i] == 1) { + tau[i] = 0. + blksize[i] = int (p2[i] - p1[i] + 1) + } else { + tau[i] = (p2[i] - p1[i]) / (npts[i] - 1) + if (tau[i] >= 2.0) { + + # If nx or ny is not an integral multiple of the block + # averaging factor, noldpix is the next larger number + # which is an integral multiple. When the image is + # block averaged pixels will be replicated as necessary + # to fill the last block out to this size. + + blksize[i] = int (tau[i]) + npix = p2[i] - p1[i] + 1 + noldpix = (npix+blksize[i]-1) / blksize[i] * blksize[i] + nbavpix = noldpix / blksize[i] + scalar = real (nbavpix - 1) / real (noldpix - 1) + p1[i] = (p1[i] - 1.0) * scalar + 1.0 + p2[i] = (p2[i] - 1.0) * scalar + 1.0 + tau[i] = (p2[i] - p1[i]) / (npts[i] - 1) + } else + blksize[i] = 1 + } + } + } + + SI_BAVG(si,1) = blksize[1] + SI_BAVG(si,2) = blksize[2] + + if (IS_INDEFI (xblk)) + xblk = blksize[1] + if (IS_INDEFI (yblk)) + yblk = blksize[2] + + # Allocate and initialize the grid arrays, specifying the X and Y + # coordinates of each pixel in the output image, in units of pixels + # in the input (possibly block averaged) image. + + do i = 1, SI_MAXDIM { + # The X coordinate is special. We do not want to read entire + # input image lines if only a range of input X values are needed. + # Since the X grid vector passed to ALUI (the interpolator) must + # contain explicit offsets into the vector being interpolated, + # we must generate interpolator grid points starting near 1.0. + # The X origin, used to read the block averaged input line, is + # given by XOFF. + + if (i == 1) { + SI_XOFF(si) = int (p1[i]) + start = p1[1] - int (p1[i]) + 1.0 + } else + start = p1[i] + + # Do the axes need to be interpolated? + if (INTVAL(start) && INTVAL(tau[i])) + SI_INTERP(si,i) = NO + else + SI_INTERP(si,i) = YES + + # Allocate grid buffer and set the grid points. + iferr (call malloc (gp, npts[i], TY_REAL)) + call erract (EA_FATAL) + SI_GRID(si,i) = gp + do j = 0, npts[i]-1 + Memr[gp+j] = start + (j * tau[i]) + } + + return (si) +end + + +# SIGL2_FREE -- Free storage associated with an image opened for scaled +# input. This does not close and unmap the image. + +procedure sigl2_free (si) + +pointer si +int i + +begin + # Free SIGL2 buffers. + do i = 1, SI_NBUFS + if (SI_BUF(si,i) != NULL) + call mfree (SI_BUF(si,i), SI_TYBUF(si)) + + # Free GRID buffers. + do i = 1, SI_MAXDIM + if (SI_GRID(si,i) != NULL) + call mfree (SI_GRID(si,i), TY_REAL) + + call mfree (si, TY_STRUCT) +end + + +# SIGL2S -- Get a line of type short from a scaled image. Block averaging is +# done by a subprocedure; this procedure gets a line from a possibly block +# averaged image and if necessary interpolates it to the grid points of the +# output line. + +pointer procedure sigl2s (si, lineno) + +pointer si # pointer to SI descriptor +int lineno + +pointer rawline, tempp, gp +int i, buf_y[2], new_y[2], tempi, curbuf, altbuf +int npix, nblks_y, ybavg, x1, x2 +real x, y, weight_1, weight_2 +pointer si_blkavgs() +errchk si_blkavgs + +begin + npix = SI_NPIX(si,1) + + # Determine the range of X (in pixels on the block averaged input image) + # required for the interpolator. + + gp = SI_GRID(si,1) + x1 = SI_XOFF(si) + x = Memr[gp+npix-1] + x2 = x1 + int(x) + if (INTVAL(x)) + x2 = x2 - 1 + x2 = max (x1 + 1, x2) + + gp = SI_GRID(si,2) + y = Memr[gp+lineno-1] + + # The following is an optimization provided for the case when it is + # not necessary to interpolate in either X or Y. Block averaging is + # permitted. + + if (SI_INTERP(si,1) == NO && SI_INTERP(si,2) == NO) + return (si_blkavgs (SI_IM(si), x1, x2, int(y), + SI_BAVG(si,1), SI_BAVG(si,2))) + + # If we are interpolating in Y two buffers are required, one for each + # of the two input image lines required to interpolate in Y. The lines + # stored in these buffers are interpolated in X to the output grid but + # not in Y. Both buffers are not required if we are not interpolating + # in Y, but we use them anyhow to simplify the code. + + if (SI_INIT(si) == YES) { + do i = 1, 2 { + if (SI_BUF(si,i) != NULL) + call mfree (SI_BUF(si,i), SI_TYBUF(si)) + call malloc (SI_BUF(si,i), npix, TY_SHORT) + SI_TYBUF(si) = TY_SHORT + buf_y[i] = NOTSET + } + if (OUTBUF(si) != NULL) + call mfree (OUTBUF(si), SI_TYBUF(si)) + call malloc (OUTBUF(si), npix, TY_SHORT) + SI_INIT(si) = NO + } + + # If the Y value of the new line is not in range of the contents of the + # current line buffers, refill one or both buffers. To refill we must + # read a (possibly block averaged) input line and interpolate it onto + # the X grid. The X and Y values herein are in the coordinate system + # of the (possibly block averaged) input image. + + new_y[1] = int(y) + new_y[2] = int(y) + 1 + + # Get the pair of lines whose integral Y values form an interval + # containing the fractional Y value of the output line. Sometimes the + # desired line will happen to be in the other buffer already, in which + # case we just have to swap buffers. Often the new line will be the + # current line, in which case nothing is done. This latter case occurs + # frequently when the magnification ratio is large. + + curbuf = 1 + altbuf = 2 + + do i = 1, 2 { + if (new_y[i] == buf_y[i]) { + ; + } else if (new_y[i] == buf_y[altbuf]) { + SWAPP (SI_BUF(si,1), SI_BUF(si,2)) + SWAPI (buf_y[1], buf_y[2]) + + } else { + # Get line and interpolate onto output grid. If interpolation + # is not required merely copy data out. This code is set up + # to always use two buffers; in effect, there is one buffer of + # look ahead, even when Y[i] is integral. This means that we + # will go out of bounds by one line at the top of the image. + # This is handled by copying the last line. + + ybavg = SI_BAVG(si,2) + nblks_y = (IM_LEN (SI_IM(si), 2) + ybavg-1) / ybavg + if (new_y[i] <= nblks_y) + rawline = si_blkavgs (SI_IM(si), x1, x2, new_y[i], + SI_BAVG(si,1), SI_BAVG(si,2)) + + if (SI_INTERP(si,1) == NO) + call amovs (Mems[rawline], Mems[SI_BUF(si,i)], npix) + else { + call aluis (Mems[rawline], Mems[SI_BUF(si,i)], + Memr[SI_GRID(si,1)], npix) + } + + buf_y[i] = new_y[i] + } + + SWAPI (altbuf, curbuf) + } + + # We now have two line buffers straddling the output Y value, + # interpolated to the X grid of the output line. To complete the + # bilinear interpolation operation we take a weighted sum of the two + # lines. If the range from buf_y[1] to buf_y[2] is repeatedly + # interpolated in Y no additional i/o occurs and the linear + # interpolation operation (ALUI) does not have to be repeated (only the + # weighted sum is required). If the distance of Y from one of the + # buffers is zero then we do not even have to take a weighted sum. + # This is not unusual because we may be called with a magnification + # of 1.0 in Y. + + weight_1 = 1.0 - (y - buf_y[1]) + weight_2 = 1.0 - weight_1 + + if (weight_2 < SI_TOL) + return (SI_BUF(si,1)) + else if (weight_1 < SI_TOL) + return (SI_BUF(si,2)) + else { + call awsus (Mems[SI_BUF(si,1)], Mems[SI_BUF(si,2)], + Mems[OUTBUF(si)], npix, weight_1, weight_2) + return (OUTBUF(si)) + } +end + + +# SI_BLKAVGS -- Get a line from a block averaged image of type short. +# For example, block averaging by a factor of 2 means that pixels 1 and 2 +# are averaged to produce the first output pixel, 3 and 4 are averaged to +# produce the second output pixel, and so on. If the length of an axis +# is not an integral multiple of the block size then the last pixel in the +# last block will be replicated to fill out the block; the average is still +# defined even if a block is not full. + +pointer procedure si_blkavgs (im, x1, x2, y, xbavg, ybavg) + +pointer im # input image +int x1, x2 # range of x blocks to be read +int y # y block to be read +int xbavg, ybavg # X and Y block averaging factors + +short temp_s +int nblks_x, nblks_y, ncols, nlines, xoff, i, j +int first_line, nlines_in_sum, npix, nfull_blks, count +real sum +pointer sp, a, b +pointer imgs2s() +errchk imgs2s + +begin + call smark (sp) + + ncols = IM_LEN(im,1) + nlines = IM_LEN(im,2) + xoff = (x1 - 1) * xbavg + 1 + npix = min (ncols, xoff + (x2 - x1 + 1) * xbavg - 1) + + if ((xbavg < 1) || (ybavg < 1)) + call error (1, "si_blkavg: illegal block size") + else if (x1 < 1 || x2 > ncols) + call error (2, "si_blkavg: column index out of bounds") + else if ((xbavg == 1) && (ybavg == 1)) + return (imgs2s (im, xoff, xoff + npix - 1, y, y)) + + nblks_x = (npix + xbavg-1) / xbavg + nblks_y = (nlines + ybavg-1) / ybavg + + if (y < 1 || y > nblks_y) + call error (2, "si_blkavg: block number out of range") + + call salloc (b, nblks_x, TY_SHORT) + + if (ybavg > 1) { + call aclrs (Mems[b], nblks_x) + nlines_in_sum = 0 + } + + # Read and accumulate all input lines in the block. + first_line = (y - 1) * ybavg + 1 + + do i = first_line, min (nlines, first_line + ybavg - 1) { + # Get line from input image. + a = imgs2s (im, xoff, xoff + npix - 1, i, i) + + # Block average line in X. + if (xbavg > 1) { + # First block average only the full blocks. + nfull_blks = npix / xbavg + call abavs (Mems[a], Mems[a], nfull_blks, xbavg) + + # Now average the final partial block, if any. + if (nfull_blks < nblks_x) { + sum = 0.0 + count = 0 + do j = nfull_blks * xbavg + 1, npix { + sum = sum + Mems[a+j-1] + count = count + 1 + } + Mems[a+nblks_x-1] = sum / count + } + } + + # Add line into block sum. Keep track of number of lines in sum + # so that we can compute block average later. + if (ybavg > 1) { + call aadds (Mems[a], Mems[b], Mems[b], nblks_x) + nlines_in_sum = nlines_in_sum + 1 + } + } + + # Compute the block average in Y from the sum of all lines block + # averaged in X. Overwrite buffer A, the buffer returned by IMIO. + # This is kosher because the block averaged line is never longer + # than an input line. + + if (ybavg > 1) { + temp_s = nlines_in_sum + call adivks (Mems[b], temp_s, Mems[a], nblks_x) + } + + call sfree (sp) + return (a) +end + + +# SIGL2R -- Get a line of type real from a scaled image. Block averaging is +# done by a subprocedure; this procedure gets a line from a possibly block +# averaged image and if necessary interpolates it to the grid points of the +# output line. + +pointer procedure sigl2r (si, lineno) + +pointer si # pointer to SI descriptor +int lineno + +pointer rawline, tempp, gp +int i, buf_y[2], new_y[2], tempi, curbuf, altbuf +int npix, nblks_y, ybavg, x1, x2 +real x, y, weight_1, weight_2 +pointer si_blkavgr() +errchk si_blkavgr + +begin + npix = SI_NPIX(si,1) + + # Deterine the range of X (in pixels on the block averaged input image) + # required for the interpolator. + + gp = SI_GRID(si,1) + x1 = SI_XOFF(si) + x = Memr[gp+npix-1] + x2 = x1 + int(x) + if (INTVAL(x)) + x2 = x2 - 1 + x2 = max (x1 + 1, x2) + + gp = SI_GRID(si,2) + y = Memr[gp+lineno-1] + + # The following is an optimization provided for the case when it is + # not necessary to interpolate in either X or Y. Block averaging is + # permitted. + + if (SI_INTERP(si,1) == NO && SI_INTERP(si,2) == NO) + return (si_blkavgr (SI_IM(si), x1, x2, int(y), + SI_BAVG(si,1), SI_BAVG(si,2))) + + # If we are interpolating in Y two buffers are required, one for each + # of the two input image lines required to interpolate in Y. The lines + # stored in these buffers are interpolated in X to the output grid but + # not in Y. Both buffers are not required if we are not interpolating + # in Y, but we use them anyhow to simplify the code. + + if (SI_INIT(si) == YES) { + do i = 1, 2 { + if (SI_BUF(si,i) != NULL) + call mfree (SI_BUF(si,i), SI_TYBUF(si)) + call malloc (SI_BUF(si,i), npix, TY_REAL) + SI_TYBUF(si) = TY_REAL + buf_y[i] = NOTSET + } + if (OUTBUF(si) != NULL) + call mfree (OUTBUF(si), SI_TYBUF(si)) + call malloc (OUTBUF(si), npix, TY_REAL) + SI_INIT(si) = NO + } + + # If the Y value of the new line is not in range of the contents of the + # current line buffers, refill one or both buffers. To refill we must + # read a (possibly block averaged) input line and interpolate it onto + # the X grid. The X and Y values herein are in the coordinate system + # of the (possibly block averaged) input image. + + new_y[1] = int(y) + new_y[2] = int(y) + 1 + + # Get the pair of lines whose integral Y values form an interval + # containing the fractional Y value of the output line. Sometimes the + # desired line will happen to be in the other buffer already, in which + # case we just have to swap buffers. Often the new line will be the + # current line, in which case nothing is done. This latter case occurs + # frequently when the magnification ratio is large. + + curbuf = 1 + altbuf = 2 + + do i = 1, 2 { + if (new_y[i] == buf_y[i]) { + ; + } else if (new_y[i] == buf_y[altbuf]) { + SWAPP (SI_BUF(si,1), SI_BUF(si,2)) + SWAPI (buf_y[1], buf_y[2]) + + } else { + # Get line and interpolate onto output grid. If interpolation + # is not required merely copy data out. This code is set up + # to always use two buffers; in effect, there is one buffer of + # look ahead, even when Y[i] is integral. This means that we + # will go out of bounds by one line at the top of the image. + # This is handled by copying the last line. + + ybavg = SI_BAVG(si,2) + nblks_y = (IM_LEN (SI_IM(si), 2) + ybavg-1) / ybavg + if (new_y[i] <= nblks_y) + rawline = si_blkavgr (SI_IM(si), x1, x2, new_y[i], + SI_BAVG(si,1), SI_BAVG(si,2)) + + if (SI_INTERP(si,1) == NO) + call amovr (Memr[rawline], Memr[SI_BUF(si,i)], npix) + else { + call aluir (Memr[rawline], Memr[SI_BUF(si,i)], + Memr[SI_GRID(si,1)], npix) + } + + buf_y[i] = new_y[i] + } + + SWAPI (altbuf, curbuf) + } + + # We now have two line buffers straddling the output Y value, + # interpolated to the X grid of the output line. To complete the + # bilinear interpolation operation we take a weighted sum of the two + # lines. If the range from buf_y[1] to buf_y[2] is repeatedly + # interpolated in Y no additional i/o occurs and the linear + # interpolation operation (ALUI) does not have to be repeated (only the + # weighted sum is required). If the distance of Y from one of the + # buffers is zero then we do not even have to take a weighted sum. + # This is not unusual because we may be called with a magnification + # of 1.0 in Y. + + weight_1 = 1.0 - (y - buf_y[1]) + weight_2 = 1.0 - weight_1 + + if (weight_2 < SI_TOL) + return (SI_BUF(si,1)) + else if (weight_1 < SI_TOL) + return (SI_BUF(si,2)) + else { + call awsur (Memr[SI_BUF(si,1)], Memr[SI_BUF(si,2)], + Memr[OUTBUF(si)], npix, weight_1, weight_2) + return (OUTBUF(si)) + } +end + + +# SI_BLKAVGR -- Get a line from a block averaged image of type short. +# For example, block averaging by a factor of 2 means that pixels 1 and 2 +# are averaged to produce the first output pixel, 3 and 4 are averaged to +# produce the second output pixel, and so on. If the length of an axis +# is not an integral multiple of the block size then the last pixel in the +# last block will be replicated to fill out the block; the average is still +# defined even if a block is not full. + +pointer procedure si_blkavgr (im, x1, x2, y, xbavg, ybavg) + +pointer im # input image +int x1, x2 # range of x blocks to be read +int y # y block to be read +int xbavg, ybavg # X and Y block averaging factors + +int nblks_x, nblks_y, ncols, nlines, xoff, i, j +int first_line, nlines_in_sum, npix, nfull_blks, count +real sum +pointer sp, a, b +pointer imgs2r() +errchk imgs2r + +begin + call smark (sp) + + ncols = IM_LEN(im,1) + nlines = IM_LEN(im,2) + xoff = (x1 - 1) * xbavg + 1 + npix = min (ncols, xoff + (x2 - x1 + 1) * xbavg - 1) + + if ((xbavg < 1) || (ybavg < 1)) + call error (1, "si_blkavg: illegal block size") + else if (x1 < 1 || x2 > ncols) + call error (2, "si_blkavg: column index out of bounds") + else if ((xbavg == 1) && (ybavg == 1)) + return (imgs2r (im, xoff, xoff + npix - 1, y, y)) + + nblks_x = (npix + xbavg-1) / xbavg + nblks_y = (nlines + ybavg-1) / ybavg + + if (y < 1 || y > nblks_y) + call error (2, "si_blkavg: block number out of range") + + call salloc (b, nblks_x, TY_REAL) + + if (ybavg > 1) { + call aclrr (Memr[b], nblks_x) + nlines_in_sum = 0 + } + + # Read and accumulate all input lines in the block. + first_line = (y - 1) * ybavg + 1 + + do i = first_line, min (nlines, first_line + ybavg - 1) { + # Get line from input image. + a = imgs2r (im, xoff, xoff + npix - 1, i, i) + + # Block average line in X. + if (xbavg > 1) { + # First block average only the full blocks. + nfull_blks = npix / xbavg + call abavr (Memr[a], Memr[a], nfull_blks, xbavg) + + # Now average the final partial block, if any. + if (nfull_blks < nblks_x) { + sum = 0.0 + count = 0 + do j = nfull_blks * xbavg + 1, npix { + sum = sum + Memr[a+j-1] + count = count + 1 + } + Memr[a+nblks_x-1] = sum / count + } + } + + # Add line into block sum. Keep track of number of lines in sum + # so that we can compute block average later. + if (ybavg > 1) { + call aaddr (Memr[a], Memr[b], Memr[b], nblks_x) + nlines_in_sum = nlines_in_sum + 1 + } + } + + # Compute the block average in Y from the sum of all lines block + # averaged in X. Overwrite buffer A, the buffer returned by IMIO. + # This is kosher because the block averaged line is never longer + # than an input line. + + if (ybavg > 1) + call adivkr (Memr[b], real(nlines_in_sum), Memr[a], nblks_x) + + call sfree (sp) + return (a) +end diff --git a/pkg/images/tv/iis/src/snap.x b/pkg/images/tv/iis/src/snap.x new file mode 100644 index 00000000..12694568 --- /dev/null +++ b/pkg/images/tv/iis/src/snap.x @@ -0,0 +1,64 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctotok.h> +include <ctype.h> +include <imhdr.h> +include <gki.h> +include "../lib/ids.h" + +# SNAP -- Take a picture!! + +procedure snap() + +char token[SZ_LINE] +int tok +char fname[SZ_FNAME] +int snap_color + +include "cv.com" + +begin + snap_color = IDS_SNAP_MONO # default color for snap + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + if (tok == TOK_IDENTIFIER) { + if (token[1] != 'c') { + call eprintf ("unknown snap argument: %s\n") + call pargstr (token) + return + } else { + # snap colors: r, g, b, rgb, m (monochrome) == bw (black/white) + switch (token[2]) { + case 'm': + snap_color = IDS_SNAP_MONO + + case 'r': + if ((token[3] == 'g') && (token[4] == 'b') ) + snap_color = IDS_SNAP_RGB + else + snap_color = IDS_SNAP_RED + + case 'g': + snap_color = IDS_SNAP_GREEN + + case 'b': + if (token[3] == 'w') + snap_color = IDS_SNAP_MONO + else + snap_color = IDS_SNAP_BLUE + + default: + call eprintf ("Unknown snap color: %c\n") + call pargc (token[2]) + return + } + } + } else if (tok != TOK_NEWLINE) { + call eprintf ("unexpected argument to snap: %s\n") + call pargstr (token) + return + } + + call clgstr("snap_file", fname, SZ_FNAME) + call cvsnap (fname, snap_color) +end diff --git a/pkg/images/tv/iis/src/split.x b/pkg/images/tv/iis/src/split.x new file mode 100644 index 00000000..393fc218 --- /dev/null +++ b/pkg/images/tv/iis/src/split.x @@ -0,0 +1,95 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctotok.h> +include <ctype.h> +include "../lib/ids.h" + +# SPLIT -- set the split screen point + +procedure split() + +char token[SZ_LINE] +int tok +int nchar, ctoi() +int i, x, y +real xr, yr +int ctor() +bool a_real + +define errmsg 10 + +include "cv.com" + +begin + a_real = false + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + if (tok == TOK_IDENTIFIER) { + switch(token[1]) { + case 'c': + x = cv_xcen + y = cv_ycen + + case 'o': + x = 1 + y = 1 + + case 'n', 'p': # n: ndc, p: pixel + if (token[1] == 'n') + a_real = true + if (IS_DIGIT(token[2])) + i = 2 + else { + call gargtok (tok, token, SZ_LINE) + if (tok != TOK_NUMBER) { +errmsg + call eprintf ("bad split pixel: %s\n") + call pargstr (token) + return + } else + i = 1 + } + if (a_real) + nchar = ctor (token, i, xr) + else + nchar = ctoi (token, i, x) + if (nchar == 0) { + call eprintf ("No conversion, ") + goto errmsg + } + call gargtok (tok, token, SZ_LINE) + if (tok == TOK_PUNCTUATION) + call gargtok (tok, token, SZ_LINE) + i = 1 + if (a_real) + nchar = ctor (token, i, yr) + else + nchar = ctoi (token, i, y) + if (nchar == 0) { + call eprintf ("No conversion, ") + goto errmsg + } + + default: + call eprintf ("unknown split code: %c\n") + call pargc (token[1]) + return + } + } + # Convert to NDC, BUT note, that as x and y range from 1 through + # cv_[xy]res, xr and yr will never be 1.0---and they must not be + # (see cvsplit()) + if (!a_real ) { + xr = real(x-1) / cv_xres + yr = real(y-1) / cv_xres + } + if ( xr < 0 ) + xr = 0 + if ( yr < 0 ) + yr = 0 + if ( xr >= 1.0 ) + xr = real(cv_xres-1)/cv_xres + if ( yr >= 1.0 ) + yr = real(cv_yres-1)/cv_yres + call cvsplit (xr, yr) +end diff --git a/pkg/images/tv/iis/src/tell.x b/pkg/images/tv/iis/src/tell.x new file mode 100644 index 00000000..cce4987e --- /dev/null +++ b/pkg/images/tv/iis/src/tell.x @@ -0,0 +1,24 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + + +include "../lib/ids.h" + +# TELL -- Tell user about display state + +procedure tell() + +short f[IDS_MAXIMPL+2] # Ultimately, want an array terminated + # with IDS_EOD as usual + +include "cv.com" + +begin + # We don't know much, do we? + + call cvwhich(f) + if ( f[1] > 0) { + call eprintf ("Frame %d, at least, is on.\n") + call pargs (f[1]) + } else + call eprintf ("No frames are on.\n") +end diff --git a/pkg/images/tv/iis/src/text.x b/pkg/images/tv/iis/src/text.x new file mode 100644 index 00000000..32623786 --- /dev/null +++ b/pkg/images/tv/iis/src/text.x @@ -0,0 +1,71 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctotok.h> +include <ctype.h> +include "../lib/ids.h" + +# TEXT -- put text into image planes or graphics bit planes + +procedure text() + +char token[SZ_LINE] +int tok, ip, cnum +short frames[IDS_MAXIMPL+2] # frames, graphics, EOD +short colors[IDS_MAXGCOLOR] +real x, y +int button, cv_wtbut() +char line[SZ_LINE] +real size, clgetr() + +begin + frames[1] = ERR + colors[1] = ERR + + # which frames for text + + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + if (tok == TOK_IDENTIFIER) { + if (token[1] == 'f') { + call cv_frame (token[2], frames) + if (frames[1] == ERR) + return + } else if (token[1] == 'c') { + call cv_color (token[2], colors) + if (colors[1] == ERR) + return + } + } else if (tok == TOK_NUMBER) { + call cv_frame (token[1], frames) + if (frames[1] == ERR) + return + } + if ( (frames[1] == ERR) && (colors[1] == ERR)) { + call eprintf ("Inadequate text specification: %s\n") + call pargstr (token) + return + } + + call gargstr (line, SZ_LINE) + + # Prompt user to set cursor + + call eprintf ("Set cursor to desired location, then press any button\n") + button = cv_wtbut() + + # Set up kernel for write + if (frames[1] != ERR) { + cnum = frames[1] + call cv_iset (frames) + } else { + cnum = 16 # SORRY, is IIS specific - we should do better + call cv_gset (colors) + } + call cv_rcur (cnum, x, y) + + size = clgetr("textsize") + ip = 1 + while (IS_WHITE(line[ip])) + ip = ip + 1 + call cvtext (x, y, line[ip], size) +end diff --git a/pkg/images/tv/iis/src/window.x b/pkg/images/tv/iis/src/window.x new file mode 100644 index 00000000..e3523a90 --- /dev/null +++ b/pkg/images/tv/iis/src/window.x @@ -0,0 +1,181 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctotok.h> +include <ctype.h> +include <gki.h> +include "../lib/ids.h" + +# WINDOW -- window the display. + +procedure window() + +char token[SZ_LINE] +int tok, cnum +short frames[IDS_MAXIMPL+2] # frames, graphics, EOD +short colors[IDS_MAXGCOLOR] +real x, y +real xold, yold +int device, button, cv_rdbut() +short wdata[16] +int n, first, last +real istart, iend, slope + +include "cv.com" + +begin + # Find out if want to change output tables + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + if (( tok == TOK_IDENTIFIER) && (token[1] == 'o')) { + device = IDS_OUTPUT_LUT + slope = 4.0 # Device dependent !! + } else { + device = IDS_FRAME_LUT + slope = 1.0 + # reset input pointers; same as having pushed back token + call reset_scan + call gargtok (tok, token, SZ_LINE) + } + + # Default to all frames, all colors + frames[1] = IDS_EOD + colors[1] = IDS_EOD + + # which frames to window + + repeat { + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + if (tok == TOK_IDENTIFIER) { + if (token[1] == 'f') { + call cv_frame (token[2], frames) + if (frames[1] == ERR) + return + } else if (token[1] == 'c') { + call cv_color (token[2], colors) + if (colors[1] == ERR) + return + } else { + call eprintf ("Unknown window argument: %s\n") + call pargstr (token) + return + } + } else if (tok == TOK_NUMBER) { + call cv_frame (token[1], frames) + if (frames[1] == ERR) + return + } else if (tok != TOK_NEWLINE) { + call eprintf ("Unexpected window input: %s\n") + call pargstr (token) + return + } + } until ( tok == TOK_NEWLINE) + + # rememeber current cursor postion + + cnum = 0 + call cv_rcur (cnum, xold, yold) + + # Now set up loop to window display; we need to read back + # display but cannot, so for now, use "common" variables + # If first time, use defaults. + + if (cv_xwinc == -1) { + if (slope == 1.0) { + cv_xwinc = 0.25 + cv_ywinc = .75 + } else { + cv_xwinc = .0625 + cv_ywinc = .9375 + } + } + call cv_scraw (cv_xwinc, cv_ywinc) + + button = cv_rdbut() # clear buttons by reading them + call eprintf ("Press any button when done\n") + + # The mapping equation is table value = 0.25 + y * (i-x) + # where i runs from 0 to 1.0, x ranges from 0. to 1.0 and y + # from 0 to large. + + repeat { + call cv_rcraw (cv_xwinc, cv_ywinc) + x = cv_xwinc + y = (cv_ywinc - 0.5) * 4 + # Keep y from equalling 2 or -2 : + if (y >= 2.) + y = 1.99 + else if ( y <= -2.0) + y = -1.99 + if (y > 1.) + y = 1. / (2. - y) + else if (y < -1.) + y = -1. / (2. + y) + + if ( y == 0.0) { + iend = 1.0 + istart = 0.0 + first = 0 + last = GKI_MAXNDC + } else if ( y > 0.) { + istart = x - 0.25/y + iend = 1.0/y + istart + first = 0 + last = GKI_MAXNDC + } else { + iend = x - 0.25/y + istart = 1.0/y + iend + first = GKI_MAXNDC + last = 0 + } + if (istart < 0.) + istart = 0. + if (iend > 1.0) + iend = 1.0 + if (istart > 1.0) + istart = 1.0 + if (iend < istart) + iend = istart + wdata[1] = 0 + if ( istart > 0.) { + wdata[2] = first + wdata[3] = istart * GKI_MAXNDC + wdata[4] = first + n = 5 + } else { + wdata[2] = (0.25 -x*y) * GKI_MAXNDC + n = 3 + } + wdata[n] = iend * GKI_MAXNDC + if ( iend < 1.0) { + # In this case, we reach max/min y value before end of table, so + # extend it horizontally to end + wdata[n+1] = last + wdata[n+2] = GKI_MAXNDC + wdata[n+3] = last + n = n + 3 + } else { + wdata[n+1] = (0.25 + y * (1.0 - x)) * GKI_MAXNDC + n = n + 1 + } + call cvwlut (device, frames, colors, wdata, n) + button = cv_rdbut() + } until (button > 0) + + # Restore old cursor position + call cv_rcur (cnum, xold, yold) + + # Tell the user what final mapping was + call printf ("window: from (%5.3f,%5.3f) to (%5.3f,%5.3f)\n") + call pargr (istart) + if (istart > 0.) + call pargr (real(first)/GKI_MAXNDC) + else + call pargr (real(wdata[2])/GKI_MAXNDC) + call pargr (iend) + if (iend < 1.0) + call pargr (real(last)/GKI_MAXNDC) + else + call pargr (real(wdata[n])/GKI_MAXNDC) + +end diff --git a/pkg/images/tv/iis/src/zoom.x b/pkg/images/tv/iis/src/zoom.x new file mode 100644 index 00000000..c7e7bff7 --- /dev/null +++ b/pkg/images/tv/iis/src/zoom.x @@ -0,0 +1,60 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctotok.h> +include <ctype.h> +include <gki.h> +include "../lib/ids.h" + +# ZOOM -- zoom, then pan, the display. If zoom power == 1, then +# don't bother panning. + +procedure zoom() + +char token[SZ_LINE] +int tok, count, power, cnum +short frames[IDS_MAXIMPL+2] # frames, graphics, EOD +real x, y +int ctoi, ip + +include "cv.com" + +begin + # get power for zoom + + call gargtok (tok, token, SZ_LINE) + if (tok != TOK_NUMBER) { + call eprintf ("Bad zoom power: %s\n") + call pargstr (token) + return + } + ip = 1 + count = ctoi(token, ip, power) + + # which frames to zoom + + frames[1] = IDS_EOD # default all frames + call gargtok (tok, token, SZ_LINE) + call strlwr (token) + if (token[1] == 'f') { + call cv_frame (token[2], frames) + if (frames[1] == ERR) + return + } else if (tok == TOK_NUMBER) { + call cv_frame (token[1], frames) + if (frames[1] == ERR) + return + } else { + call eprintf ("Unexpected input: %s\n") + call pargstr (token) + return + } + + # where to zoom ... find which frame to read cursor position from + + cnum = frames[1] + if (cnum == IDS_EOD) + cnum = 0 + call cv_rcur (cnum, x, y) + call cvzoom (frames, power, x, y) + call pansub (frames) +end diff --git a/pkg/images/tv/iis/src/zscale.x b/pkg/images/tv/iis/src/zscale.x new file mode 100644 index 00000000..bfb0b116 --- /dev/null +++ b/pkg/images/tv/iis/src/zscale.x @@ -0,0 +1,457 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <imhdr.h> + +.help zscale +.nf ___________________________________________________________________________ +ZSCALE -- Compute the optimal Z1, Z2 (range of greyscale values to be +displayed) of an image. For efficiency a statistical subsample of an image +is used. The pixel sample evenly subsamples the image in x and y. The entire +image is used if the number of pixels in the image is smaller than the desired +sample. + +The sample is accumulated in a buffer and sorted by greyscale value. +The median value is the central value of the sorted array. The slope of a +straight line fitted to the sorted sample is a measure of the standard +deviation of the sample about the median value. Our algorithm is to sort +the sample and perform an iterative fit of a straight line to the sample, +using pixel rejection to omit gross deviants near the endpoints. The fitted +straight line is the transfer function used to map image Z into display Z. +If more than half the pixels are rejected the full range is used. The slope +of the fitted line is divided by the user-supplied contrast factor and the +final Z1 and Z2 are computed, taking the origin of the fitted line at the +median value. +.endhelp ______________________________________________________________________ + +define MIN_NPIXELS 5 # smallest permissible sample +define MAX_REJECT 0.5 # max frac. of pixels to be rejected +define GOOD_PIXEL 0 # use pixel in fit +define BAD_PIXEL 1 # ignore pixel in all computations +define REJECT_PIXEL 2 # reject pixel after a bit +define KREJ 2.5 # k-sigma pixel rejection factor +define MAX_ITERATIONS 5 # maximum number of fitline iterations + + +# ZSCALE -- Sample the image and compute Z1 and Z2. + +procedure zscale (im, z1, z2, contrast, optimal_sample_size, len_stdline) + +pointer im # image to be sampled +real z1, z2 # output min and max greyscale values +real contrast # adj. to slope of transfer function +int optimal_sample_size # desired number of pixels in sample +int len_stdline # optimal number of pixels per line + +int npix, minpix, ngoodpix, center_pixel, ngrow +real zmin, zmax, median +real zstart, zslope +pointer sample, left +int zsc_sample_image(), zsc_fit_line() + +begin + # Subsample the image. + npix = zsc_sample_image (im, sample, optimal_sample_size, len_stdline) + center_pixel = max (1, (npix + 1) / 2) + + # Sort the sample, compute the minimum, maximum, and median pixel + # values. + + call asrtr (Memr[sample], Memr[sample], npix) + zmin = Memr[sample] + zmax = Memr[sample+npix-1] + + # The median value is the average of the two central values if there + # are an even number of pixels in the sample. + + left = sample + center_pixel - 1 + if (mod (npix, 2) == 1 || center_pixel >= npix) + median = Memr[left] + else + median = (Memr[left] + Memr[left+1]) / 2 + + # Fit a line to the sorted sample vector. If more than half of the + # pixels in the sample are rejected give up and return the full range. + # If the user-supplied contrast factor is not 1.0 adjust the scale + # accordingly and compute Z1 and Z2, the y intercepts at indices 1 and + # npix. + + minpix = max (MIN_NPIXELS, int (npix * MAX_REJECT)) + ngrow = max (1, nint (npix * .01)) + ngoodpix = zsc_fit_line (Memr[sample], npix, zstart, zslope, + KREJ, ngrow, MAX_ITERATIONS) + + if (ngoodpix < minpix) { + z1 = zmin + z2 = zmax + } else { + if (contrast > 0) + zslope = zslope / contrast + z1 = max (zmin, median - (center_pixel - 1) * zslope) + z2 = min (zmax, median + (npix - center_pixel) * zslope) + } + + call mfree (sample, TY_REAL) +end + + +# ZSC_SAMPLE_IMAGE -- Extract an evenly gridded subsample of the pixels from +# a two-dimensional image into a one-dimensional vector. + +int procedure zsc_sample_image (im, sample, optimal_sample_size, len_stdline) + +pointer im # image to be sampled +pointer sample # output vector containing the sample +int optimal_sample_size # desired number of pixels in sample +int len_stdline # optimal number of pixels per line + +int ncols, nlines, col_step, line_step, maxpix, line +int opt_npix_per_line, npix_per_line +int opt_nlines_in_sample, min_nlines_in_sample, max_nlines_in_sample +pointer op +pointer imgl2r() + +begin + ncols = IM_LEN(im,1) + nlines = IM_LEN(im,2) + + # Compute the number of pixels each line will contribute to the sample, + # and the subsampling step size for a line. The sampling grid must + # span the whole line on a uniform grid. + + opt_npix_per_line = min (ncols, len_stdline) + col_step = (ncols + opt_npix_per_line-1) / opt_npix_per_line + npix_per_line = (ncols + col_step-1) / col_step + + # Compute the number of lines to sample and the spacing between lines. + # We must ensure that the image is adequately sampled despite its + # size, hence there is a lower limit on the number of lines in the + # sample. We also want to minimize the number of lines accessed when + # accessing a large image, because each disk seek and read is expensive. + # The number of lines extracted will be roughly the sample size divided + # by len_stdline, possibly more if the lines are very short. + + min_nlines_in_sample = max (1, optimal_sample_size / len_stdline) + opt_nlines_in_sample = max(min_nlines_in_sample, min(nlines, + (optimal_sample_size + npix_per_line-1) / npix_per_line)) + line_step = max (1, nlines / (opt_nlines_in_sample)) + max_nlines_in_sample = (nlines + line_step-1) / line_step + + # Allocate space for the output vector. Buffer must be freed by our + # caller. + + maxpix = npix_per_line * max_nlines_in_sample + call malloc (sample, maxpix, TY_REAL) + +# call eprintf ("sample: x[%d:%d:%d] y[%d:%d:%d]\n") +# call pargi(1);call pargi(ncols); call pargi(col_step) +# call pargi((line_step+1)/2); call pargi(nlines); call pargi(line_step) + + # Extract the vector. + op = sample + do line = (line_step + 1) / 2, nlines, line_step { + call zsc_subsample (Memr[imgl2r(im,line)], Memr[op], + npix_per_line, col_step) + op = op + npix_per_line + if (op - sample + npix_per_line > maxpix) + break + } + + return (op - sample) +end + + +# ZSC_SUBSAMPLE -- Subsample an image line. Extract the first pixel and +# every "step"th pixel thereafter for a total of npix pixels. + +procedure zsc_subsample (a, b, npix, step) + +real a[ARB] +real b[npix] +int npix, step +int ip, i + +begin + if (step <= 1) + call amovr (a, b, npix) + else { + ip = 1 + do i = 1, npix { + b[i] = a[ip] + ip = ip + step + } + } +end + + +# ZSC_FIT_LINE -- Fit a straight line to a data array of type real. This is +# an iterative fitting algorithm, wherein points further than ksigma from the +# current fit are excluded from the next fit. Convergence occurs when the +# next iteration does not decrease the number of pixels in the fit, or when +# there are no pixels left. The number of pixels left after pixel rejection +# is returned as the function value. + +int procedure zsc_fit_line (data, npix, zstart, zslope, krej, ngrow, maxiter) + +real data[npix] # data to be fitted +int npix # number of pixels before rejection +real zstart # Z-value of pixel data[1] (output) +real zslope # dz/pixel (output) +real krej # k-sigma pixel rejection factor +int ngrow # number of pixels of growing +int maxiter # max iterations + +int i, ngoodpix, last_ngoodpix, minpix, niter +real xscale, z0, dz, x, z, mean, sigma, threshold +double sumxsqr, sumxz, sumz, sumx, rowrat +pointer sp, flat, badpix, normx +int zsc_reject_pixels(), zsc_compute_sigma() + +begin + call smark (sp) + + if (npix <= 0) + return (0) + else if (npix == 1) { + zstart = data[1] + zslope = 0.0 + return (1) + } else + xscale = 2.0 / (npix - 1) + + # Allocate a buffer for data minus fitted curve, another for the + # normalized X values, and another to flag rejected pixels. + + call salloc (flat, npix, TY_REAL) + call salloc (normx, npix, TY_REAL) + call salloc (badpix, npix, TY_SHORT) + call aclrs (Mems[badpix], npix) + + # Compute normalized X vector. The data X values [1:npix] are + # normalized to the range [-1:1]. This diagonalizes the lsq matrix + # and reduces its condition number. + + do i = 0, npix - 1 + Memr[normx+i] = i * xscale - 1.0 + + # Fit a line with no pixel rejection. Accumulate the elements of the + # matrix and data vector. The matrix M is diagonal with + # M[1,1] = sum x**2 and M[2,2] = ngoodpix. The data vector is + # DV[1] = sum (data[i] * x[i]) and DV[2] = sum (data[i]). + + sumxsqr = 0 + sumxz = 0 + sumx = 0 + sumz = 0 + + do i = 1, npix { + x = Memr[normx+i-1] + z = data[i] + sumxsqr = sumxsqr + (x ** 2) + sumxz = sumxz + z * x + sumz = sumz + z + } +# call eprintf ("\t%10g %10g %10g\n") +# call pargd(sumxsqr); call pargd(sumxz); call pargd(sumz) + + # Solve for the coefficients of the fitted line. + z0 = sumz / npix + dz = sumxz / sumxsqr + +# call eprintf ("fit: z0=%g, dz=%g\n") +# call pargr(z0); call pargr(dz) + + # Iterate, fitting a new line in each iteration. Compute the flattened + # data vector and the sigma of the flat vector. Compute the lower and + # upper k-sigma pixel rejection thresholds. Run down the flat array + # and detect pixels to be rejected from the fit. Reject pixels from + # the fit by subtracting their contributions from the matrix sums and + # marking the pixel as rejected. + + ngoodpix = npix + minpix = max (MIN_NPIXELS, int (npix * MAX_REJECT)) + + for (niter=1; niter <= maxiter; niter=niter+1) { + last_ngoodpix = ngoodpix + + # Subtract the fitted line from the data array. + call zsc_flatten_data (data, Memr[flat], Memr[normx], npix, z0, dz) + + # Compute the k-sigma rejection threshold. In principle this + # could be more efficiently computed using the matrix sums + # accumulated when the line was fitted, but there are problems with + # numerical stability with that approach. + + ngoodpix = zsc_compute_sigma (Memr[flat], Mems[badpix], npix, + mean, sigma) + threshold = sigma * krej + + # Detect and reject pixels further than ksigma from the fitted + # line. + ngoodpix = zsc_reject_pixels (data, Memr[flat], Memr[normx], + Mems[badpix], npix, sumxsqr, sumxz, sumx, sumz, threshold, + ngrow) + + # Solve for the coefficients of the fitted line. Note that after + # pixel rejection the sum of the X values need no longer be zero. + + if (ngoodpix > 0) { + rowrat = sumx / sumxsqr + z0 = (sumz - rowrat * sumxz) / (ngoodpix - rowrat * sumx) + dz = (sumxz - z0 * sumx) / sumxsqr + } + +# call eprintf ("fit: z0=%g, dz=%g, threshold=%g, npix=%d\n") +# call pargr(z0); call pargr(dz); call pargr(threshold); call pargi(ngoodpix) + + if (ngoodpix >= last_ngoodpix || ngoodpix < minpix) + break + } + + # Transform the line coefficients back to the X range [1:npix]. + zstart = z0 - dz + zslope = dz * xscale + + call sfree (sp) + return (ngoodpix) +end + + +# ZSC_FLATTEN_DATA -- Compute and subtract the fitted line from the data array, +# returned the flattened data in FLAT. + +procedure zsc_flatten_data (data, flat, x, npix, z0, dz) + +real data[npix] # raw data array +real flat[npix] # flattened data (output) +real x[npix] # x value of each pixel +int npix # number of pixels +real z0, dz # z-intercept, dz/dx of fitted line +int i + +begin + do i = 1, npix + flat[i] = data[i] - (x[i] * dz + z0) +end + + +# ZSC_COMPUTE_SIGMA -- Compute the root mean square deviation from the +# mean of a flattened array. Ignore rejected pixels. + +int procedure zsc_compute_sigma (a, badpix, npix, mean, sigma) + +real a[npix] # flattened data array +short badpix[npix] # bad pixel flags (!= 0 if bad pixel) +int npix +real mean, sigma # (output) + +real pixval +int i, ngoodpix +double sum, sumsq, temp + +begin + sum = 0 + sumsq = 0 + ngoodpix = 0 + + # Accumulate sum and sum of squares. + do i = 1, npix + if (badpix[i] == GOOD_PIXEL) { + pixval = a[i] + ngoodpix = ngoodpix + 1 + sum = sum + pixval + sumsq = sumsq + pixval ** 2 + } + + # Compute mean and sigma. + switch (ngoodpix) { + case 0: + mean = INDEF + sigma = INDEF + case 1: + mean = sum + sigma = INDEF + default: + mean = sum / ngoodpix + temp = sumsq / (ngoodpix - 1) - sum**2 / (ngoodpix * (ngoodpix - 1)) + if (temp < 0) # possible with roundoff error + sigma = 0.0 + else + sigma = sqrt (temp) + } + + return (ngoodpix) +end + + +# ZSC_REJECT_PIXELS -- Detect and reject pixels more than "threshold" greyscale +# units from the fitted line. The residuals about the fitted line are given +# by the "flat" array, while the raw data is in "data". Each time a pixel +# is rejected subtract its contributions from the matrix sums and flag the +# pixel as rejected. When a pixel is rejected reject its neighbors out to +# a specified radius as well. This speeds up convergence considerably and +# produces a more stringent rejection criteria which takes advantage of the +# fact that bad pixels tend to be clumped. The number of pixels left in the +# fit is returned as the function value. + +int procedure zsc_reject_pixels (data, flat, normx, badpix, npix, + sumxsqr, sumxz, sumx, sumz, threshold, ngrow) + +real data[npix] # raw data array +real flat[npix] # flattened data array +real normx[npix] # normalized x values of pixels +short badpix[npix] # bad pixel flags (!= 0 if bad pixel) +int npix +double sumxsqr,sumxz,sumx,sumz # matrix sums +real threshold # threshold for pixel rejection +int ngrow # number of pixels of growing + +int ngoodpix, i, j +real residual, lcut, hcut +double x, z + +begin + ngoodpix = npix + lcut = -threshold + hcut = threshold + + do i = 1, npix + if (badpix[i] == BAD_PIXEL) + ngoodpix = ngoodpix - 1 + else { + residual = flat[i] + if (residual < lcut || residual > hcut) { + # Reject the pixel and its neighbors out to the growing + # radius. We must be careful how we do this to avoid + # directional effects. Do not turn off thresholding on + # pixels in the forward direction; mark them for rejection + # but do not reject until they have been thresholded. + # If this is not done growing will not be symmetric. + + do j = max(1,i-ngrow), min(npix,i+ngrow) { +#call eprintf ("\t\t%d->%d\tcheck\n");call pargi(j); call pargs(badpix[j]) + if (badpix[j] != BAD_PIXEL) { + if (j <= i) { + x = normx[j] + z = data[j] +#call eprintf ("\treject [%d:%6g]=%6g sum[xsqr,xz,z]\n") +#call pargi(j); call pargd(x); call pargd(z) +#call eprintf ("\t%10g %10g %10g\n") +#call pargd(sumxsqr); call pargd(sumxz); call pargd(sumz) + sumxsqr = sumxsqr - (x ** 2) + sumxz = sumxz - z * x + sumx = sumx - x + sumz = sumz - z +#call eprintf ("\t%10g %10g %10g\n") +#call pargd(sumxsqr); call pargd(sumxz); call pargd(sumz) + badpix[j] = BAD_PIXEL + ngoodpix = ngoodpix - 1 + } else + badpix[j] = REJECT_PIXEL +#call eprintf ("\t\t%d->%d\tset\n");call pargi(j); call pargs(badpix[j]) + } + } + } + } + + return (ngoodpix) +end diff --git a/pkg/images/tv/iis/window.cl b/pkg/images/tv/iis/window.cl new file mode 100644 index 00000000..25f00c65 --- /dev/null +++ b/pkg/images/tv/iis/window.cl @@ -0,0 +1,5 @@ +#{ WINDOW -- Adjust the lookup tables for the current frame. + +{ + _dcontrol (type="frame", window+) +} diff --git a/pkg/images/tv/iis/x_iis.x b/pkg/images/tv/iis/x_iis.x new file mode 100644 index 00000000..06813f75 --- /dev/null +++ b/pkg/images/tv/iis/x_iis.x @@ -0,0 +1,7 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +# Driver for image control + +task cv = t_cv, + cvl = t_load + #giis = t_giis diff --git a/pkg/images/tv/iis/zoom.cl b/pkg/images/tv/iis/zoom.cl new file mode 100644 index 00000000..9aa48959 --- /dev/null +++ b/pkg/images/tv/iis/zoom.cl @@ -0,0 +1,11 @@ +#{ ZOOM -- Zoom in on a portion of the display. + +# zoom_factor,i,a,2,1,4,factor by which image scale is to be expanded +# window,b,h,no,,,window enlarged image + +{ + if (window) + _dcontrol (zoom=zoom_factor, roam=yes, window=yes) + else + _dcontrol (zoom=zoom_factor, roam=yes) +} diff --git a/pkg/images/tv/iis/zoom.par b/pkg/images/tv/iis/zoom.par new file mode 100644 index 00000000..849c3439 --- /dev/null +++ b/pkg/images/tv/iis/zoom.par @@ -0,0 +1,2 @@ +zoom_factor,i,a,2,1,4,factor by which image scale is to be expanded +window,b,h,no,,,window enlarged image |