diff options
Diffstat (limited to 'pkg/images/tv/imedit/t_imedit.x')
-rw-r--r-- | pkg/images/tv/imedit/t_imedit.x | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/pkg/images/tv/imedit/t_imedit.x b/pkg/images/tv/imedit/t_imedit.x new file mode 100644 index 00000000..984ce86b --- /dev/null +++ b/pkg/images/tv/imedit/t_imedit.x @@ -0,0 +1,305 @@ +include <error.h> +include <imhdr.h> +include "epix.h" + +define HELP "imedit_help$" +define PROMPT "imedit options" + +# T_IMEDIT -- Edit image pixels. +# This task provides selection of pixels to be edit via cursor or file +# input. The regions to be edited may be defined as a rectangle or a +# center and radius for a circular or square aperture. The replacement +# options include constant substitution, background substitution, column +# or line interpolation, and moving one region to another. In addition +# this task can be used to select and display regions in surface perspective +# and to print statistics. The image display interface temporarily +# used simple calls to a user specified display task (such as TV.DISPLAY). +# The editing is done in a temporary image buffer. The commands which +# alter the input image may be logged if a log file is given. + +procedure t_imedit () + +int inlist # List of input images +int outlist # List of output images + +int i, key, ap, xa, ya, xb, yb, x1, x2, y1, y2 +int change, changes, newdisplay, newimage +bool erase +pointer sp, ep, cmd, temp +pointer im + +bool streq() +pointer immap(), imgl2r(), impl2r() +int imtopenp(), imtlen(), imtgetim(), imaccess(), ep_gcur() +errchk immap, imdelete, ep_imcopy, ep_setpars, imgl2r, impl2r + +define newim_ 99 + +begin + call smark (sp) + call salloc (cmd, SZ_LINE, TY_CHAR) + + # Allocate and initialize imedit descriptor. + call salloc (ep, EP_LEN, TY_STRUCT) + call aclri (Memi[ep], EP_LEN) + + # Check the input and output image lists have proper format. + inlist = imtopenp ("input") + outlist = imtopenp ("output") + if (imtlen (outlist) > 0 && imtlen (outlist) != imtlen (inlist)) + call error (1, "Input and output lists are not the same length") + + # Set the rest of the task parameters. + call ep_setpars (ep) + + # Repeat on each input image. + while (imtgetim (inlist, EP_INPUT(ep), EP_SZFNAME) != EOF) { + if (imtgetim (outlist, EP_OUTPUT(ep), EP_SZFNAME) == EOF) + call strcpy (EP_INPUT(ep), EP_OUTPUT(ep), EP_SZFNAME) + else if (imaccess (EP_OUTPUT(ep), READ_ONLY) == YES) { + call eprintf ("%s: Output image %s exists\n") + call pargstr (EP_INPUT(ep)) + call pargstr (EP_OUTPUT(ep)) + next + } + + # The editing takes place in a temporary editing image buffer. +newim_ call strcpy (EP_OUTPUT(ep), EP_WORK(ep), EP_SZFNAME) + call xt_mkimtemp (EP_OUTPUT(ep), EP_WORK(ep), EP_OUTPUT(ep), + EP_SZFNAME) + iferr (call ep_imcopy (EP_INPUT(ep), EP_WORK(ep))) { + call erract (EA_WARN) + next + } + + EP_IM(ep) = immap (EP_WORK(ep), READ_WRITE, 0) + EP_INDATA(ep) = NULL + EP_OUTDATA(ep) = NULL + + if (EP_LOGFD(ep) != NULL) { + call fprintf (EP_LOGFD(ep), "# Input image %s\n") + call pargstr (EP_INPUT(ep)) + } + + if (EP_DISPLAY(ep) == YES) { + key = '0' + call ep_zoom (ep, xa, ya, xb, yb, key, erase) + call ep_command (ep, EP_WORK(ep), erase) + } + + + # Enter the cursor loop. The apertures and commands are + # returned by the EP_GCUR procedure. + + newimage = NO + changes = 0 + while (ep_gcur (ep,ap,xa,ya,xb,yb,key,Memc[cmd],SZ_LINE) != EOF) { + newdisplay = NO + change = NO + + iferr { + switch (key) { + case '?': # Print help + call pagefile (HELP, PROMPT) + case ':': # Process colon commands + call ep_colon (ep, Memc[cmd], newimage) + if (newimage == YES) + break + case 'a', 'b': # Background replacement + call ep_background (ep, ap, xa, ya, xb, yb) + if (EP_OUTDATA(ep) != NULL) { + change = YES + changes = changes + 1 + } + case 'c': # Column interpolation + call ep_col (ep, ap, xa, ya, xb, yb) + if (EP_OUTDATA(ep) != NULL) { + change = YES + changes = changes + 1 + } + case 'd', 'e', 'v': # Constant value + call ep_constant (ep, ap, xa, ya, xb, yb) + if (EP_OUTDATA(ep) != NULL) { + change = YES + changes = changes + 1 + } + case 'f': # Diagonal aperture + if (ap == APCDIAG) + call ep_col (ep, ap, xa, ya, xb, yb) + else + call ep_line (ep, ap, xa, ya, xb, yb) + if (EP_OUTDATA(ep) != NULL) { + change = YES + changes = changes + 1 + } + case '=', '<', '>': # Replace + if (IM_PIXTYPE(EP_IM(ep)) == TY_INT) + call ep_replacei (ep, xa, ya, key) + else + call ep_replacer (ep, xa, ya, key) + if (EP_OUTDATA(ep) != NULL) { + change = YES + changes = changes + 1 + } + case 'i': # Initialize + call imunmap (EP_IM(ep)) + goto newim_ + case 'j', 'k': # Replace with input + call ep_input (ep, ap, xa, ya, xb, yb) + if (EP_OUTDATA(ep) != NULL) { + change = YES + changes = changes + 1 + } + case 'l': # Line interpolation + call ep_line (ep, ap, xa, ya, xb, yb) + if (EP_OUTDATA(ep) != NULL) { + change = YES + changes = changes + 1 + } + case 'm', 'n': # Move + i = ep_gcur (ep, ap, x1, y1, x2, y2, key, + Memc[cmd],SZ_LINE) + call ep_move (ep, ap, xa, ya, xb, yb, x1, y1, x2, y2, + key) + if (EP_OUTDATA(ep) != NULL) { + change = YES + changes = changes + 1 + } + case 'g': # Surface graph + call ep_dosurface (ep) + case ' ': # Statistics + call ep_statistics (ep, ap, xa, ya, xb, yb, NO) + case 'p': + call ep_statistics (ep, ap, xa, ya, xb, yb, YES) + case 't': + EP_SEARCH(ep) = -EP_SEARCH(ep) + call ep_colon (ep, "search", newimage) + case '+': + EP_RADIUS(ep) = EP_RADIUS(ep) + 1. + call ep_colon (ep, "radius", newimage) + case '-': + EP_RADIUS(ep) = max (0., EP_RADIUS(ep) - 1.) + call ep_colon (ep, "radius", newimage) + case 's': # Surface plot + i = max (5., + abs (EP_SEARCH(ep))+EP_BUFFER(ep)+EP_WIDTH(ep)+1) + x1 = min (xa, xb) - i + x2 = max (xa, xb) + i + y1 = min (ya, yb) - i + y2 = max (ya, yb) + i + call ep_gindata (ep, x1, x2, y1, y2) + EP_OUTDATA(ep) = NULL + call ep_dosurface (ep) + case 'q': # Quit and save + case 'u': # Undo + if (EP_OUTDATA(ep) != NULL && EP_INDATA(ep) != NULL) { + call malloc (temp, EP_NPTS(ep), TY_REAL) + call amovr (Memr[EP_OUTDATA(ep)], Memr[temp], + EP_NPTS(ep)) + call amovr (Memr[EP_INDATA(ep)], + Memr[EP_OUTDATA(ep)], EP_NPTS(ep)) + call amovr (Memr[temp], Memr[EP_INDATA(ep)], + EP_NPTS(ep)) + call mfree (temp, TY_REAL) + change = YES + } else + call eprintf ("Can't undo last change\007\n") + case 'r', 'E', 'P', 'R', 'Z', '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9': + if (EP_DISPLAY(ep) == YES) { + call ep_zoom (ep, xa, ya, xb, yb, key, erase) + newdisplay = YES + } + case 'Q': # Quit and no save + changes = 0 + case 'I': # Immediate interrupt + call imdelete (EP_WORK(ep)) + call fatal (1, "Interrupt") + default: + call printf ("\007") + } + } then + call erract (EA_WARN) + + if (key == 'q' || key == 'Q') + break + + if (change == YES && EP_AUTOSURFACE(ep) == YES) + call ep_dosurface (ep) + + if (change == YES && EP_AUTODISPLAY(ep) == YES) + newdisplay = YES + if (newdisplay == YES && EP_DISPLAY(ep) == YES) + call ep_display (ep, EP_WORK(ep), erase) + + # Log certain commands. Note that this is done after + # centering. + if (EP_LOGFD(ep) != NULL) { + switch (key) { + case 'a', 'c', 'd', 'f', 'j', 'l', 'v': + call fprintf (EP_LOGFD(ep), "%d %d 1 %c\n") + call pargi (xa) + call pargi (ya) + call pargi (key) + call fprintf (EP_LOGFD(ep), "%d %d 1 %c\n") + call pargi (xb) + call pargi (yb) + call pargi (key) + case 'b', 'e', 'k': + call fprintf (EP_LOGFD(ep), "%d %d 1 %c\n") + call pargi ((xa+xb)/2) + call pargi ((ya+yb)/2) + call pargi (key) + case 'u': + if (EP_OUTDATA(ep) != NULL) { + call fprintf (EP_LOGFD(ep), "%c\n") + call pargi (key) + } + case 'm', 'n': + call fprintf (EP_LOGFD(ep), "%d %d 1 %c\n") + call pargi ((xa+xb)/2) + call pargi ((ya+yb)/2) + call pargi (key) + call fprintf (EP_LOGFD(ep), "%d %d 1 %c\n") + call pargi ((x1+x2)/2) + call pargi ((y1+y2)/2) + call pargi (key) + } + } + } + + call imunmap (EP_IM(ep)) + # Only create the output if the input has been changed. + if (changes > 0) { + if (streq (EP_INPUT(ep), EP_OUTPUT(ep))) { + EP_IM(ep) = immap (EP_OUTPUT(ep), READ_WRITE, 0) + im = immap (EP_WORK(ep), READ_ONLY, 0) + do i = 1, IM_LEN(EP_IM(ep),2) + call amovr (Memr[imgl2r(im,i)], + Memr[impl2r(EP_IM(ep),i)], IM_LEN(im,1)) + call imunmap (im) + call imunmap (EP_IM(ep)) + call imdelete (EP_WORK(ep)) + } else { + if (imaccess (EP_OUTPUT(ep), READ_ONLY) == YES) + call imdelete (EP_OUTPUT(ep)) + call imrename (EP_WORK(ep), EP_OUTPUT(ep)) + } + } else + call imdelete (EP_WORK(ep)) + + # Check for a new image based on a colon command. This case + # always uses the input image name as output. + if (newimage == YES) { + call strcpy (EP_INPUT(ep), EP_OUTPUT(ep), EP_SZFNAME) + goto newim_ + } + } + + # Finish up. + if (EP_LOGFD(ep) != NULL) + call close (EP_LOGFD(ep)) + call imtclose (inlist) + call imtclose (outlist) + call sfree (sp) +end |