home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume7 / image / part04 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  51.4 KB

  1. Subject:  v07i067:  Image manipulation routines in C++, Part04/05
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: David Sher <seismo!rochester!sher>
  6. Mod.sources: Volume 7, Issue 67
  7. Archive-name: image/Part04
  8.  
  9. [  The Makefiles had ESCAPE and \r characters in their comment lines;
  10.    I changed them to their printable representation, the two-character
  11.    sequences ^[ and ^M, respectively.  Also, the file ascii2var/uu.test.var
  12.    had some non-ASCII characters in it; I used uuencode; the resultant
  13.    file is really ascii2var/test.var.  Also, I do not have C++ nor any
  14.    images, so I have not tested this package.  --r$  ]
  15.  
  16. #!/bin/sh
  17. # This is a shell archive.  Remove anything before this line,
  18. # then unpack it by saving it in a file and typing "sh file".
  19. # If all goes well, you will see the message "No problems found."
  20. # Wrapped by mirror!rs on Mon Nov 10 13:44:37 EST 1986
  21.  
  22. # Exit status; set to 1 on "wc" errors or if would overwrite.
  23. STATUS=0
  24. # Contents:  varc++/long_image.c++ varc++/image.c++
  25. #    varc++/image.c.old varc++/double_image.c++ vartools/trunc.c++
  26. #    vartools/scale.c++ vartools/correlate.c++
  27.  
  28. echo x - varc++/long_image.c++
  29. if test -f varc++/long_image.c++ ; then
  30.     echo varc++/long_image.c++ exists, putting output in $$varc++/long_image.c++
  31.     OUT=$$varc++/long_image.c++
  32.     STATUS=1
  33. else
  34.     OUT=varc++/long_image.c++
  35. fi
  36. sed 's/^X//' > $OUT <<'@//E*O*F varc++/long_image.c++//'
  37. X/*
  38. X    This file contains the routines necessary to manipulate an image
  39. X    of 8 bit data that do not need to know about the image file format
  40. X*/
  41.  
  42. X#include <stream.h>
  43. X#include <stdio.h>
  44.  
  45. X#include "for.h++"
  46.  
  47. X#include "long_image.h++"
  48.  
  49.  
  50. X/* the constructor when the image is built */
  51. Xlong_image::long_image 
  52. X    ( 
  53. X    const create_image_type cit ,    // marker that the image is being created
  54. X    const card n_rows ,         // the number of rows in the image
  55. X    const card n_cols ,         // the number of collumns in the image
  56. X    const FILE * image_file ,    // file for image
  57. X    const card w_width = 1 ,    // window width
  58. X    const card w_length = 1     // window length
  59. X    )
  60. X    : ( CREATE , image_file , n_rows , n_cols , w_width , w_length )
  61. X    {
  62. X    /* check that the constructor is called correctly */
  63. X    if ( cit != CREATE )
  64. X    {
  65. X    cerr << "constructor for long_image being called in obscure way\n";
  66. X    abort();
  67. X    }
  68. X    
  69. X    /* allocate space for image */
  70. X    image_buffer = new long [ n_rows*n_cols ];
  71.  
  72. X    /* allocate space for dope vector */
  73. X    image_rows = new long * [ n_rows ];
  74. X    /* allocate space for window dope vector */
  75. X    window_rows = new long * [ w_length ];
  76.  
  77. X    /* initialize dope vector */
  78. X    FOR(int i1 = 0 ; i1 < n_rows; i1++)
  79. X    {
  80. X    image_rows[i1] = image_buffer + i1*n_cols;
  81. X    }
  82. X    ENDFOR
  83.  
  84. X    /* set up the protection  so the image can be written */
  85. X    prot = CAN_WRITE;
  86.  
  87. X    /* initialize function pointers */
  88. X    next = &uninitialized_next;
  89. X    prev = &uninitialized_prev;
  90. X    get_w_e_pointer = &uninitialized_get_w_e;
  91. X    write_w_e_pointer = &uninitialized_write_w_e;
  92. X    }
  93.  
  94.  
  95. X/* functions for function pointers */
  96.  
  97. X/* this version of next assumes the window has been initialized */
  98. Xint 
  99. Xlong_image::initialized_next ()
  100. X    {
  101. X    // if at the end of a row
  102. X    if ( collumn + window_width == number_cols )
  103. X    {
  104. X    // if at the end of the image
  105. X    if ( row + window_length == number_rows )
  106. X        {
  107. X        return 0;
  108. X        }
  109. X    // otherwise go to the beginning of the next row
  110. X    collumn = 0;
  111. X    row++;
  112. X    // reset the pointers in the window
  113. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  114. X        {
  115. X        window_rows[i1] = image_rows[row + i1];
  116. X        }
  117. X    ENDFOR
  118. X    // return successfully
  119. X    return 1;
  120. X    }
  121. X    // otherwise move along row
  122. X    collumn++;
  123. X    // move the pointers in the window
  124. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  125. X    {
  126. X    window_rows[i1]++;
  127. X    }
  128. X    ENDFOR
  129. X    // return successfully
  130. X    return 1;
  131. X    }
  132.  
  133. X/* this version of prev assumes the window has been initialized */
  134. Xint 
  135. Xlong_image::initialized_prev ()
  136. X    {
  137. X    // if at beginning of a row
  138. X    if ( collumn == 0 )
  139. X    {
  140. X    // if at the beginning of the image
  141. X    if ( row == 0 )
  142. X        {
  143. X        return 0;
  144. X        }
  145. X    // otherwise go to the end of the previous row
  146. X    collumn = number_cols - window_width;
  147. X    row--;
  148. X    // reset the pointers in the window
  149. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  150. X        {
  151. X        window_rows[i1] = image_rows[row + i1] + collumn;
  152. X        }
  153. X    ENDFOR
  154. X    // return successfully
  155. X    return 1;
  156. X    }
  157. X    // otherwise move back on the row
  158. X    collumn--;
  159. X    // move the pointers in the window
  160. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  161. X    {
  162. X    window_rows[i1]--;
  163. X    }
  164. X    ENDFOR
  165. X    // return successfully
  166. X    return 1;
  167. X    }
  168.  
  169. X/* this version of next initializes the window */
  170. Xint 
  171. Xlong_image::uninitialized_next ()
  172. X    {
  173. X    // check that the window fits in the image
  174. X    if ( (window_width > number_cols) || (window_length > number_rows) )
  175. X    {
  176. X    return 0;
  177. X    }
  178.  
  179. X    // set row and collumn to 0
  180. X    row = 0;
  181. X    collumn = 0;
  182.  
  183. X    // set the window row pointers
  184. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  185. X    {
  186. X    window_rows[i1] = image_rows[row + i1];
  187. X    }
  188. X    ENDFOR
  189.  
  190. X    // set the function pointers
  191. X    next = &initialized_next;
  192. X    prev = &initialized_prev;
  193. X    get_w_e_pointer = &initialized_get_w_e;
  194. X    write_w_e_pointer = &initialized_write_w_e;
  195.  
  196. X    // set the window status
  197. X    window_status = INITIALIZED;
  198. X    return 1;
  199. X    }
  200.  
  201. X/* this version of prev initializes the window */
  202. Xint 
  203. Xlong_image::uninitialized_prev ()
  204. X    {
  205. X    // check that the window fits in the image
  206. X    if ( (window_width > number_cols) || (window_length > number_rows) )
  207. X    {
  208. X    return 0;
  209. X    }
  210.  
  211. X    // set row and collumn to bottom right of image
  212. X    row = number_rows - window_length;
  213. X    collumn = number_cols - window_width;
  214. X    // set the window row pointers
  215. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  216. X    {
  217. X    window_rows[i1] = image_rows[row + i1] + collumn;
  218. X    }
  219. X    ENDFOR
  220.  
  221. X    // set the function pointers
  222. X    next = &initialized_next;
  223. X    prev = &initialized_prev;
  224. X    get_w_e_pointer = &initialized_get_w_e;
  225. X    write_w_e_pointer = &initialized_write_w_e;
  226.  
  227. X    // set the window status
  228. X    window_status = INITIALIZED;
  229. X    return 1;
  230. X    }
  231.  
  232. X// this version of next says that applying the next operation is impossible
  233. Xint
  234. Xlong_image::impossible_next ( )
  235. X    {
  236. X    cerr << "Trying to apply the next operation to an image for which it is impossible!\n";
  237. X    return 0;
  238. X    }
  239.  
  240. X// this version of prev says that applying the next operation is impossible
  241. Xint
  242. Xlong_image::impossible_prev ( )
  243. X    {
  244. X    cerr << "Trying to apply the prev operation to an image for which it is impossible!\n";
  245. X    return 0;
  246. X    }
  247.  
  248. X/* uninitialized version of get_w_e will just die */
  249. Xlong 
  250. Xlong_image::uninitialized_get_w_e ( const card i , const card j )
  251. X    {
  252. X    cerr << "Trying to get an element of an uninitialized window\n";
  253. X    cerr << "The element was " << i << "," << j << "\n";
  254. X    abort ();
  255. X    return 0;
  256. X    }
  257.  
  258. X/* initialized version of get_w_e */
  259. Xlong 
  260. Xlong_image::initialized_get_w_e ( const card i , const card j )
  261. X    {
  262. X    // check that i,j is in the window
  263. X    if ( ( i >= window_length ) || ( j >= window_width ) )
  264. X    {
  265. X    cerr << "Tried to access element outside window\n";
  266. X    cerr << "Window size " << window_length << "," << window_width << "\n";
  267. X    cerr << "Accessed " << i << "," << j << "\n";
  268. X    abort ();
  269. X    return 0;
  270. X    }
  271. X    
  272. X    // otherwise return the element
  273. X    return window_rows[i][j];
  274. X    }
  275.  
  276. X/* uninitialized version of write_w_e will just die */
  277. Xvoid 
  278. Xlong_image::uninitialized_write_w_e ( const card i , const card j , const long value )
  279. X    {
  280. X    cerr << "Trying to write to an element of an uninitialized window\n";
  281. X    cerr << "Trying to write " << value << "\n";
  282. X    cerr << "To " << i << "," << j << "\n";
  283. X    abort ();
  284. X    }
  285.  
  286. X/* initialized version of write_w_e */
  287. Xvoid 
  288. Xlong_image::initialized_write_w_e ( const card i , const card j , const long value)
  289. X    {
  290. X    // check that i,j is in the window
  291. X    if ( ( i >= window_length ) || ( j >= window_width ) )
  292. X    {
  293. X    cerr << "Tried to access element outside window\n";
  294. X    cerr << "Window size " << window_length << "," << window_width << "\n";
  295. X    cerr << "Accessed " << i << "," << j << "\n";
  296. X    abort ();
  297. X    }
  298. X    
  299. X    // otherwise set the element
  300. X    window_rows[i][j] = value;
  301. X    }
  302.  
  303. X/*
  304. X    move in row n steps 
  305. X    returns 1 when that motion is legal 0 otherwise
  306. X*/
  307. Xint 
  308. Xlong_image::move_collumn ( const int n ) 
  309. X    {
  310. X    // the version in image does the checking and most of the work
  311. X    int result = image_class::move_collumn ( n );
  312.  
  313. X    // if the move was successful move the window
  314. X    if ( result == 1 )
  315. X    {
  316. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  317. X        {
  318. X        window_rows[i1] += n;
  319. X        }
  320. X    ENDFOR
  321. X    }
  322.  
  323. X    return result;
  324. X    }
  325.  
  326. X/*
  327. X    move in collumn n steps
  328. X    returns 1 when that motion is legal 0 otherwise
  329. X*/
  330. Xint 
  331. Xlong_image::move_row ( const int n ) 
  332. X    {
  333. X    // the version in image does the checking and most of the work
  334. X    int result = image_class::move_row ( n );
  335.  
  336. X    // if the move was successful move the window
  337. X    if ( result == 1 )
  338. X    {
  339. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  340. X        {
  341. X        window_rows[i1] = image_rows[row + i1] + collumn ;
  342. X        }
  343. X    ENDFOR
  344. X    }
  345.  
  346. X    return result;
  347. X    }
  348.  
  349.  
  350. X/*
  351. X    move to specified row
  352. X*/
  353. Xvoid 
  354. Xlong_image::move_to_row ( const card n ) 
  355. X    {
  356. X    // the version in image does the checking and most of the work
  357. X    image_class::move_to_row ( n );
  358.  
  359. X    // move the window to the specified place
  360. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  361. X    {
  362. X    window_rows[i1] = image_rows[row + i1] + collumn ;
  363. X    }
  364. X    ENDFOR
  365. X    }
  366.  
  367.  
  368. X/*
  369. X    move to specified collumn
  370. X*/
  371. Xvoid 
  372. Xlong_image::move_to_collumn ( const card n ) 
  373. X    {
  374. X    // the version in image does the checking and most of the work
  375. X    image_class::move_to_collumn ( n );
  376.  
  377. X    // move the window to the specified place
  378. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  379. X    {
  380. X    window_rows[i1] = image_rows[row + i1] + collumn ;
  381. X    }
  382. X    ENDFOR
  383. X    }
  384.  
  385. X/*
  386. X    Gets a pointer to a row
  387. X    of the image
  388. X*/
  389. Xconst long * 
  390. Xlong_image::get_row( card row )
  391. X    {
  392. X    // Checks to make sure request is legal
  393. X    if ( row >= number_rows )
  394. X    {
  395. X    cerr << "Tried to accesses row " << row;
  396. X    cerr << " when image only has " << number_rows << " rows!\n";
  397. X    abort();
  398. X    }
  399. X    if ( image_status == UNINITIALIZED )
  400. X    {
  401. X    cerr << "Trying to read row from unitialized image!\n";
  402. X    abort();
  403. X    }
  404. X    if ( (prot != CAN_READ) && (prot != CAN_READ_AND_WRITE) )
  405. X    {
  406. X    cerr << "Trying to access a row of an image protected against reading!\n";
  407. X    abort();
  408. X    }
  409. X    
  410. X    return image_rows[row];
  411. X    }
  412.  
  413. X/*
  414. X    Change the size of a window
  415. X    causes the window to become uninitialized
  416. X*/
  417. Xvoid 
  418. Xlong_image::resize_window ( card width , card length )
  419. X    {
  420.  
  421. X    // set the window
  422. X    window_width = width;
  423. X    window_length = length;
  424. X    window_status = UNINITIALIZED;
  425.  
  426. X    /* allocate space for window dope vector */
  427. X    window_rows = new long * [ window_length ];
  428.  
  429. X    /* reset function pointers */
  430. X    next = &uninitialized_next;
  431. X    prev = &uninitialized_prev;
  432. X    get_w_e_pointer = &uninitialized_get_w_e;
  433. X    write_w_e_pointer = &uninitialized_write_w_e;
  434. X    }
  435.  
  436. X/*
  437. X    Causes the window to cover the entire image.
  438. X    Allows one to access any part of the image with window operations
  439. X*/
  440. Xvoid 
  441. Xlong_image::window_entire_image ( )
  442. X    {
  443. X    // set up the window
  444. X    window_width = number_cols;
  445. X    window_length = number_rows;
  446. X    window_status = INITIALIZED;
  447. X    // make the window dope vector an alias for the image dope vector
  448. X    window_rows = image_rows;
  449.  
  450. X    // set up function pointers so next and previous impossible
  451. X    next = &impossible_next;
  452. X    prev = &impossible_prev;
  453. X    // access functions
  454. X    get_w_e_pointer = &initialized_get_w_e;
  455. X    write_w_e_pointer = &initialized_write_w_e;
  456. X    }
  457. X/*
  458. XCopyright (C) 1986, David Sher in the University of Rochester
  459. XPermission is granted to any individual or institution to use, copy, or
  460. Xredistribute this software so long as it is not sold for profit, provided
  461. Xthis copyright notice is retained.
  462. X*/
  463. @//E*O*F varc++/long_image.c++//
  464. chmod u=rw,g=r,o=r $OUT
  465.  
  466. echo x - varc++/image.c++
  467. if test -f varc++/image.c++ ; then
  468.     echo varc++/image.c++ exists, putting output in $$varc++/image.c++
  469.     OUT=$$varc++/image.c++
  470.     STATUS=1
  471. else
  472.     OUT=varc++/image.c++
  473. fi
  474. sed 's/^X//' > $OUT <<'@//E*O*F varc++/image.c++//'
  475. X/*
  476. X    This file contains the implementation of the generic image stuff
  477. X    except for handling the and read and write function that 
  478. X    requires knowledge of the image file format
  479. X*/
  480. X#include <stream.h>
  481. X#include <stdio.h>
  482. X#include <string.h>
  483. X#include "for.h++"
  484. X#include "image.h++"
  485.  
  486. X/*
  487. X    initializer for generic images when image is being created rather
  488. X    than read from file
  489. X*/
  490. Ximage_class::image_class
  491. X    ( 
  492. X    const create_image_type cit,    // maker that the image is being created
  493. X    const FILE * image_file ,     // the file for the image
  494. X    const card n_rows ,         // the number of rows in the image
  495. X    const card n_cols ,         // the number of collumns in the image
  496. X    const card w_width ,         // the width of the window
  497. X    const card w_length         // the length of the window
  498. X    )
  499. X    {
  500. X    /* check that the constructor is called correctly */
  501. X    if ( cit != CREATE )
  502. X    {
  503. X    cerr << "Generic constructor for image being called in obscure way\n";
  504. X    abort();
  505. X    }
  506.  
  507. X    /* initialize using arguments */
  508. X    file = image_file;
  509. X    number_rows = n_rows;
  510. X    number_cols = n_cols;
  511. X    window_width = w_width;
  512. X    window_length = w_length;
  513.  
  514. X    /* a priori initializations */
  515. X    /* status */
  516. X    image_status = UNINITIALIZED;
  517. X    window_status = UNINITIALIZED;
  518. X    prot = CAN_NOT_DO_ANYTHING;
  519. X    /* comments */
  520. X    comment_length = 0;
  521. X    comments = NULL;
  522. X    /* header info from file format */
  523. X    header_info = NULL;
  524. X    }
  525.  
  526. X/*
  527. X    comment manipulation code
  528. X*/
  529. X/* 
  530. X    returns a null terminated string for comments 
  531. X*/
  532. Xconst char * 
  533. Xcomment_string ( image_class& i )
  534. X    {
  535. X    char * output = new char [ i.comment_length + 1 ];    // output for the data
  536. X    char * output_p = output;                // pointer to output
  537. X    const char * com = i.comments;            // comments
  538.  
  539. X    /* copy the comments into the new string */
  540. X    FOR(int i1 = 0 ; i1 < i.comment_length ; i1++)
  541. X    {
  542. X    *(output_p++) = *(com++);
  543. X    }
  544. X    ENDFOR
  545.  
  546. X    /* null terminate the new string */
  547. X    *output_p = '\0';
  548.  
  549. X    /* return the new string */
  550. X    return output;
  551. X    }
  552.  
  553. X/* sets the comments */
  554. Xvoid 
  555. Ximage_class::set_comments( char * string , const card length )
  556. X    {
  557. X    comment_length = length;
  558. X    comments = string;
  559. X    }
  560.  
  561. X/* adds a string to the comments */
  562. Xvoid 
  563. Ximage_class::add_comment( char * string , const card length )
  564. X    {
  565. X    /* the new comments to be used */
  566. X    char * new_comments = new char [ comment_length + length ];
  567. X    char * ncp = new_comments;    // pointer into new comments
  568. X    char * ocp = comments;    // pointer into old comments
  569.  
  570. X    /* copy the old comments into the new string */
  571. X    FOR(int i1 = 0 ; i1 < comment_length ; i1++)
  572. X    {
  573. X    *(ncp++) = *(ocp++);
  574. X    }
  575. X    ENDFOR
  576. X    
  577. X    /* copy the added comments into the new string */
  578. X    FOR(int i1 = 0 ; i1 < length ; i1++)
  579. X    {
  580. X    *(ncp++) = *(string++);
  581. X    }
  582. X    ENDFOR
  583.  
  584. X    /* make the new string the comments */
  585. X    comment_length += length;
  586. X    comments = new_comments;
  587. X    }
  588.  
  589. X/*
  590. X    for moving around in images
  591. X*/
  592.  
  593. X/*
  594. X    move to specified row
  595. X*/
  596. Xvoid 
  597. Ximage_class::move_to_row ( const card n ) 
  598. X    {
  599. X    // test bounds
  600. X    if ( n < 0 ) 
  601. X    {
  602. X    cerr << "Trying to move to a negative row in an image\n";
  603. X    cerr << "The row is " << n << "\n";
  604. X    abort();
  605. X    }
  606. X    if ( n + window_length > number_rows )
  607. X    {
  608. X    cerr << "Trying to move to a nonexistant row in an image\n";
  609. X    cerr << "The row is " << n << "\n";
  610. X    abort();
  611. X    }
  612.  
  613. X    // check status
  614. X    if ( window_status == UNINITIALIZED )
  615. X    {
  616. X    // check collumn boundaries
  617. X    if ( window_width > number_cols )
  618. X        {
  619. X        cerr << "Window to wide for image!\n";
  620. X        cerr << "Width of image: " << number_cols;
  621. X        cerr << "Width of window: " << window_width;
  622. X        cerr << "\n";
  623. X        abort();
  624. X        }
  625. X    row = n;
  626. X    collumn = 0;
  627. X    window_status = INITIALIZED;
  628. X    }
  629.  
  630. X    // otherwise change the row since it is legal
  631. X    row = n;
  632. X    }
  633.  
  634. X/*
  635. X    move to specified collumn
  636. X*/
  637. Xvoid 
  638. Ximage_class::move_to_collumn ( const card n ) 
  639. X    {
  640. X    // test bounds
  641. X    if ( n < 0 ) 
  642. X    {
  643. X    cerr << "Trying to move to a negative collumn in an image\n";
  644. X    cerr << "The collumn is " << n << "\n";
  645. X    abort();
  646. X    }
  647. X    if ( n + window_width > number_cols )
  648. X    {
  649. X    cerr << "Trying to move to a nonexistant collumn in an image\n";
  650. X    cerr << "The collumn is " << n << "\n";
  651. X    abort();
  652. X    }
  653.  
  654. X    // check status
  655. X    if ( window_status == UNINITIALIZED )
  656. X    {
  657. X    // check collumn boundaries
  658. X    if ( window_length > number_rows )
  659. X        {
  660. X        cerr << "Window to long for image!\n";
  661. X        cerr << "Height of image: " << number_rows;
  662. X        cerr << "Height of window: " << window_length;
  663. X        cerr << "\n";
  664. X        abort();
  665. X        }
  666. X    collumn = n;
  667. X    row = 0;
  668. X    window_status = INITIALIZED;
  669. X    }
  670.  
  671. X    // otherwise change the row since it is legal
  672. X    collumn = n;
  673. X    }
  674.  
  675. X/*
  676. X    move in row n steps 
  677. X    returns 1 when that motion is legal 0 otherwise
  678. X*/
  679. Xint 
  680. Ximage_class::move_collumn ( const int n ) 
  681. X    {
  682. X    // check the status of the window
  683. X    if ( window_status == UNINITIALIZED )
  684. X    {
  685. X    // it is probably an error so print an error message
  686. X    cerr << "trying to move in unitialized window\n";
  687. X    // but return 0 since  that is the semantics
  688. X    return 0;
  689. X    }
  690. X    
  691. X    // check that the movement doesn't lead to a negative position
  692. X    if ( n + collumn < 0 )
  693. X    {
  694. X    return 0;
  695. X    }
  696. X    
  697. X    // check that the movement doesn't lead to a too large position
  698. X    if ( n + collumn + window_width > number_rows )
  699. X    {
  700. X    return 0;
  701. X    }
  702. X    
  703. X    // else increment the collumn position and return successfully
  704. X    collumn += n;
  705. X    return 1;
  706. X    }
  707.  
  708. X/*
  709. X    move in collumn n steps
  710. X    returns 1 when that motion is legal 0 otherwise
  711. X*/
  712. Xint 
  713. Ximage_class::move_row ( const int n ) 
  714. X    {
  715. X    // check the status of the window
  716. X    if ( window_status == UNINITIALIZED )
  717. X    {
  718. X    // it is probably an error so print an error message
  719. X    cerr << "trying to move in unitialized window\n";
  720. X    // but return 0 since  that is the semantics
  721. X    return 0;
  722. X    }
  723. X    
  724. X    // check that the movement doesn't lead to a negative position
  725. X    if ( n + row < 0 )
  726. X    {
  727. X    return 0;
  728. X    }
  729. X    
  730. X    // check that the movement doesn't lead to a too large position
  731. X    if ( n + row + window_width > number_cols )
  732. X    {
  733. X    return 0;
  734. X    }
  735. X    
  736. X    // else increment the collumn position and return successfully
  737. X    row += n;
  738. X    return 1;
  739. X    }
  740.  
  741. X/* change the protection from CAN_WRITE to CAN_READ_AND_WRITE */
  742. Xvoid image_class::read_and_write ( )
  743. X    { 
  744. X    if ( prot == CAN_WRITE ) 
  745. X    {
  746. X    prot = CAN_READ_AND_WRITE;
  747. X    }
  748. X    else
  749. X    {
  750. X    cerr << "Protection violation for read_and_write\n";
  751. X    abort();
  752. X    }
  753. X    }
  754.  
  755. X/*
  756. XCopyright (C) 1986, David Sher in the University of Rochester
  757. XPermission is granted to any individual or institution to use, copy, or
  758. Xredistribute this software so long as it is not sold for profit, provided
  759. Xthis copyright notice is retained.
  760. X*/
  761. @//E*O*F varc++/image.c++//
  762. chmod u=rw,g=r,o=r $OUT
  763.  
  764. echo x - varc++/image.c.old
  765. if test -f varc++/image.c.old ; then
  766.     echo varc++/image.c.old exists, putting output in $$varc++/image.c.old
  767.     OUT=$$varc++/image.c.old
  768.     STATUS=1
  769. else
  770.     OUT=varc++/image.c.old
  771. fi
  772. sed 's/^X//' > $OUT <<'@//E*O*F varc++/image.c.old//'
  773. X/*
  774. X    This file contains the routines that interface to the maryland
  775. X    vision package
  776. X*/
  777.  
  778. X#include <stdio.h>
  779. X#include "utils.h"
  780. X#include "image.h"
  781.  
  782.  
  783. X/*
  784. X    Creates an image Data Structure
  785. X*/
  786. Ximage_pt
  787. Xcreate_image(number_rows,number_cols)
  788. Xcard number_rows;    /* Number of rows */
  789. Xcard number_cols;    /* Number of cols */
  790. X    {
  791. X    register card i;
  792.  
  793. X/* Allocate space for the image data structure */
  794. X    image_pt output = (image_pt) MALLOC(sizeof(image));
  795. X    if(output == NULL)
  796. X    {
  797. X    perror("CreateImage:MALLOC failed");
  798. X    abort();
  799. X    }
  800.  
  801. X/* Should set up defaults properly */
  802. X    mhead(&(output->head), number_cols, number_rows);
  803.  
  804. X/* Make sure defaults are correct */
  805. X    output->head.cv_lcom = 0;
  806. X    output->head.cv_type = 0;
  807. X    output->head.cv_dims = 2;
  808. X    output->head.cv_hpls = 1;
  809. X    output->head.cv_bnds = 1;
  810. X    output->head.cv_bp = sizeof(image_elt)*8;
  811. X    output->head.cv_ebb = 0;
  812. X    output->head.cv_sbb = sizeof(image_elt)*8;
  813. X    output->head.cv_bb = sizeof(image_elt)*8;
  814. X    output->head.cv_sbp = sizeof(image_elt)*8;
  815. X    output->head.cv_ebp = 0;
  816.  
  817. X/* Allocate the dope vector for the image array */
  818. X    output->array = (image_elt **) MALLOC
  819. X                (
  820. X                sizeof(image_elt *) 
  821. X                * output->head.cv_rows
  822. X                );
  823. X    
  824. X/* Allocate the storage areas for the image array */
  825. X    for(i = 0; i < output->head.cv_rows; i++)
  826. X    {
  827. X    output->array[i] = (image_elt *) MALLOC 
  828. X                (
  829. X                sizeof(image_elt) 
  830. X                * output->head.cv_cols
  831. X                );
  832. X        if(output->array[i] == NULL)
  833. X        {
  834. X        perror("CreateImage:MALLOC failed");
  835. X        abort();
  836. X        }
  837.  
  838. X    }
  839.  
  840. X/* Describe there being 0 lines of comments */
  841. X    output->comment.number_lines = 0;
  842. X    output->comment.line_lengths = NULL;
  843. X    output->comment.lines = NULL;
  844.  
  845. X/* return the processed output */
  846. X    return output;
  847. X    }
  848.  
  849. X/*
  850. X    Reads in an image from a file
  851. X*/
  852. Ximage_pt
  853. Xread_image(f)
  854. Xint f;    /* file descriptor to read image from */
  855. X    {
  856. X    register card i;
  857.  
  858. X/* Allocate space for the image data structure */
  859. X    image_pt output = (image_pt) MALLOC(sizeof(image));
  860.  
  861. X/* Create the mv header */
  862. X    ihead(f,&(output->head));
  863.  
  864. X/* Read in the image comments */
  865. X    read_comments(f,output);
  866.  
  867. X/* Allocate the dope vector for the image array */
  868. X    output->array = (image_elt **) MALLOC
  869. X                (
  870. X                sizeof(image_elt *) 
  871. X                * output->head.cv_rows
  872. X                );
  873. X    if(output == NULL)
  874. X    {
  875. X    perror("ReadImage:MALLOC failed");
  876. X    abort();
  877. X    }
  878. X    
  879. X/* Allocate the storage areas for the image array */
  880. X    for(i = 0; i < output->head.cv_rows; i++)
  881. X    {
  882. X    output->array[i] = (image_elt *) MALLOC 
  883. X                (
  884. X                sizeof(image_elt) 
  885. X                * output->head.cv_cols
  886. X                );
  887. X        if(output->array[i] == NULL)
  888. X        {
  889. X        perror("ReadImage:MALLOC failed");
  890. X        abort();
  891. X        }
  892.  
  893. X    /* Read in a row of the image into the new array */
  894. X    rrow8(f,output->array[i],&(output->head));
  895.  
  896. X#ifdef DEBUG
  897. X    fprintf(stderr,"read row %d 1st element is %d\n",i,output->array[i][0]);
  898. X#endif DEBUG
  899. X    }
  900.  
  901. X/* return the processed output */
  902. X    return output;
  903. X    }
  904.  
  905.  
  906. X/*
  907. X    Writes an image out to a file
  908. X*/
  909. Xvoid
  910. Xwrite_image(f,input)
  911. Xint f;    /* file to write image to */
  912. Ximage_pt input;    /* image to write */
  913. X    {
  914. X    register card i;
  915.  
  916. X/* Write out image header */
  917. X    ohead(f,&(input->head));
  918.  
  919. X/* Write comments to file */
  920. X    write_comments(f,&(input->comment));
  921.  
  922. X/* Write out image array */
  923. X    for(i = 0; i < input->head.cv_rows; i++)
  924. X    {
  925. X    /* Write out a row of the image from the image array */
  926. X    wrow8(f,input->array[i],&(input->head));
  927. X    }
  928. X    }
  929.  
  930.  
  931. X/*
  932. X    routines to manipulate floating images
  933. X*/
  934.  
  935. X/*
  936. X    Creates an floating image Data Structure
  937. X*/
  938. Xfloat_image_pt
  939. Xfloat_create_image(number_rows,number_cols)
  940. Xcard number_rows;    /* Number of rows */
  941. Xcard number_cols;    /* Number of cols */
  942. X    {
  943. X    register card i;
  944.  
  945. X/* Allocate space for the image data structure */
  946. X    float_image_pt output = (float_image_pt) MALLOC(sizeof(float_image));
  947. X    if(output == NULL)
  948. X    {
  949. X    perror("CreateImage:MALLOC failed");
  950. X    abort();
  951. X    }
  952.  
  953. X/* Should set up defaults properly */
  954. X    mhead(&(output->head), number_cols, number_rows);
  955.  
  956. X/* Make sure defaults are correct */
  957. X    output->head.cv_lcom = 0;
  958. X    output->head.cv_type = 0;
  959. X    output->head.cv_dims = 2;
  960. X    output->head.cv_hpls = 1;
  961. X    output->head.cv_bnds = 1;
  962. X    output->head.cv_bp = sizeof(double)*8;
  963. X    output->head.cv_ebb = 8;
  964. X    output->head.cv_sbb = sizeof(double)*8;
  965. X    output->head.cv_bb = sizeof(double)*8;
  966. X    output->head.cv_sbp = sizeof(double)*8;
  967. X    output->head.cv_ebp = 8;
  968.  
  969. X/* Allocate the dope vector for the image array */
  970. X    output->array = (double **) MALLOC
  971. X                (
  972. X                sizeof(double *) 
  973. X                * output->head.cv_rows
  974. X                );
  975. X    
  976. X/* Allocate the storage areas for the image array */
  977. X    for(i = 0; i < output->head.cv_rows; i++)
  978. X    {
  979. X    output->array[i] = (double *) MALLOC 
  980. X                (
  981. X                sizeof(double) 
  982. X                * output->head.cv_cols
  983. X                );
  984. X        if(output->array[i] == NULL)
  985. X        {
  986. X        perror("CreateImage:MALLOC failed");
  987. X        abort();
  988. X        }
  989.  
  990. X    }
  991.  
  992. X/* Describe there being 0 lines of comments */
  993. X    output->comment.number_lines = 0;
  994. X    output->comment.line_lengths = NULL;
  995. X    output->comment.lines = NULL;
  996.  
  997. X/* return the processed output */
  998. X    return output;
  999. X    }
  1000.  
  1001. X/*
  1002. X    Reads in an floating image from a file
  1003. X*/
  1004. Xfloat_image_pt
  1005. Xfloat_read_image(f)
  1006. Xint f;    /* file descriptor to read image from */
  1007. X    {
  1008. X    register card i;
  1009.  
  1010. X/* Allocate space for the image data structure */
  1011. X    float_image_pt output = (float_image_pt) MALLOC(sizeof(float_image));
  1012.  
  1013. X/* Create the mv header */
  1014. X    ihead(f,&(output->head));
  1015.  
  1016. X/* Read in the image comments */
  1017. X    read_comments(f,output);
  1018.  
  1019. X/* Allocate the dope vector for the image array */
  1020. X    output->array = (double **) MALLOC
  1021. X                (
  1022. X                sizeof(double *) 
  1023. X                * output->head.cv_rows
  1024. X                );
  1025. X    if(output == NULL)
  1026. X    {
  1027. X    perror("ReadImage:MALLOC failed");
  1028. X    abort();
  1029. X    }
  1030. X    
  1031. X/* Allocate the storage areas for the image array */
  1032. X    for(i = 0; i < output->head.cv_rows; i++)
  1033. X    {
  1034. X    output->array[i] = (double *) MALLOC 
  1035. X                (
  1036. X                sizeof(double) 
  1037. X                * output->head.cv_cols
  1038. X                );
  1039. X        if(output->array[i] == NULL)
  1040. X        {
  1041. X        perror("ReadImage:MALLOC failed");
  1042. X        abort();
  1043. X        }
  1044.  
  1045. X#ifndef MVWORKS
  1046. X    /* This code should work but doesn't  so ... */
  1047. X    /* Read in a row of the image into the new array */
  1048. X    rrowd(f,output->array[i],&(output->head));
  1049. X#else
  1050. X/* This only works for reading floating point images */
  1051. X        read(f,(char *) output->array[i],output->head.cv_cols * sizeof(double));
  1052. X#endif MVWORKS
  1053. X    }
  1054.  
  1055. X/* return the processed output */
  1056. X    return output;
  1057. X    }
  1058.  
  1059.  
  1060. X/*
  1061. X    Writes an floating image out to a file
  1062. X*/
  1063. Xvoid
  1064. Xfloat_write_image(f,input)
  1065. Xint f;    /* file to write image to */
  1066. Xfloat_image_pt input;    /* image to write */
  1067. X    {
  1068. X    register card i;
  1069.  
  1070. X/* Write out image header */
  1071. X    ohead(f,&(input->head));
  1072.  
  1073. X/* Write comments to file */
  1074. X    write_comments(f,&(input->comment));
  1075.  
  1076. X/* Write out image array */
  1077. X    for(i = 0; i < input->head.cv_rows; i++)
  1078. X    {
  1079. X#ifndef MVWORKS
  1080. X    /* This code should work but doesn't  so ... */
  1081. X    /* Write out a row of the image from the image array */
  1082. X    wrowd(f,input->array[i],&(input->head));
  1083. X#else
  1084. X/* This only works for writing floating point images */
  1085. X        write(f,(char *) input->array[i],input->head.cv_cols * sizeof(double));
  1086. X#endif MVWORKS
  1087. X    }
  1088. X    }
  1089.  
  1090.  
  1091. X/*
  1092. X    Reads comments from image
  1093. X*/
  1094. Xvoid
  1095. Xread_comments(f,input)
  1096. Xint f;    /* file descriptor */
  1097. Ximage_pt input;    /* image */
  1098. X    {
  1099. X    char *buffer;
  1100. X    int read_result;
  1101. X    int read_total = 0;
  1102.  
  1103. X    if (input->head.cv_lcom == 0) 
  1104. X    {
  1105. X    input->comment.number_lines = 0;
  1106. X    input->comment.line_lengths = NULL;
  1107. X    input->comment.lines = NULL;
  1108. X    return;
  1109. X    }
  1110.  
  1111. X    buffer = (char *) MALLOC(input->head.cv_lcom * sizeof(char));
  1112.  
  1113. X/* If there is a problem reading the comments */
  1114. X    while(input->head.cv_lcom != ( read_total += (read_result = read(f,buffer+read_total,input->head.cv_lcom - read_total))))
  1115. X    {
  1116. X    if ( read_result == -1 ) 
  1117. X        {
  1118. X        perror("Could not read comments");
  1119. X        abort();
  1120. X        }
  1121. X    else if( read_result == 0 ) 
  1122. X        {
  1123. X        fprintf(stderr,"Could only read %d bytes of comments when there is supposed to be %d bytes!\n",read_total,input->head.cv_lcom);
  1124. X        abort();
  1125. X        }
  1126. X    }
  1127.  
  1128. X/* Allocates things for comments and reads them */
  1129. X    input->comment.number_lines = find_number_of_lines(buffer,(card) input->head.cv_lcom);
  1130. X    input->comment.line_lengths = (card *) MALLOC((input->comment.number_lines*sizeof(card)));
  1131. X    input->comment.lines = (char **) MALLOC(input->comment.number_lines*sizeof(char *));
  1132. X    allocate_lines(buffer,(card) input->head.cv_lcom,input->comment.line_lengths,input->comment.lines);
  1133. X    }
  1134.  
  1135. X/*
  1136. X    finds number of lines in comment
  1137. X*/
  1138. Xcard
  1139. Xfind_number_of_lines(buffer,size)
  1140. Xchar buffer[];
  1141. Xcard size;
  1142. X    {
  1143. X    register card i;
  1144. X    register char *pc = buffer;
  1145. X    card num_lines = 1;
  1146. X    for(i = 0 ; i < size; i++) 
  1147. X    {
  1148. X    if(*pc == '\n') num_lines++;
  1149. X    pc++;
  1150. X    }
  1151. X    return num_lines;
  1152. X    }
  1153.  
  1154. X/*
  1155. X    allocates space and inserts the lines of the image into the right
  1156. X    places in lines
  1157. X*/
  1158. Xvoid
  1159. Xallocate_lines(buffer,size,line_lengths,lines)
  1160. Xchar buffer[];
  1161. Xcard size;
  1162. Xcard line_lengths[];
  1163. Xchar *lines[];
  1164. X    {
  1165. X    register card i,j;
  1166. X    register char *pc = buffer;
  1167. X    register char *begin_line = buffer;
  1168. X    card current_line = 0;
  1169. X    card current_size = 0;
  1170. X    for(i = 0 ; i < size; i++) 
  1171. X    {
  1172. X    /* If at end of line */
  1173. X    if(*pc == '\n')
  1174. X        {
  1175. X    /* fill in size of line */
  1176. X        line_lengths[current_line] = current_size;
  1177. X    /* allocate space for line */
  1178. X        lines[current_line] = MALLOC((current_size + 1)*sizeof(char));
  1179. X    /* read line into lines array */
  1180. X        for(j = 0 ; j < current_size ; j++) 
  1181. X        {
  1182. X        lines[current_line][j] = *begin_line;
  1183. X        begin_line++;
  1184. X        }
  1185. X    /* set end marker in lines array */
  1186. X        lines[current_line][j] = 0;
  1187. X    /* set current size to 0 */
  1188. X        current_size = 0;
  1189. X    /* set begin_line to the beginning of the next line */
  1190. X        begin_line++;
  1191. X    /* set current_line to the next line */
  1192. X        current_line++;
  1193. X        }
  1194. X    else 
  1195. X        {
  1196. X    /* current size is increased */
  1197. X        current_size++;
  1198. X        }
  1199. X    pc++;
  1200. X    }
  1201.  
  1202. X/* Do last line in image */
  1203.  
  1204. X/* fill in size of line */
  1205. X    line_lengths[current_line] = current_size;
  1206. X/* allocate space for line */
  1207. X    lines[current_line] = MALLOC((current_size + 1)*sizeof(char));
  1208. X/* read line into lines array */
  1209. X    for(j = 0 ; j < current_size ; j++) 
  1210. X        {
  1211. X        lines[current_line][j] = *begin_line;
  1212. X    begin_line++;
  1213. X    }
  1214. X/* set end marker in lines array */
  1215. X    lines[current_line][j] = 0;
  1216. X    }
  1217.  
  1218.  
  1219.  
  1220. X/*
  1221. X    Writes comments to image
  1222. X*/
  1223. Xvoid
  1224. Xwrite_comments(file,comment)
  1225. Xint file;
  1226. Ximage_comment *comment;
  1227. X    {
  1228. X    register card i;
  1229. X    int write_return;
  1230. X    for(i = 0;i < comment->number_lines; i++)
  1231. X    {
  1232. X    write_return = write(file,comment->lines[i],(int) comment->line_lengths[i]);
  1233. X    if(write_return != comment->line_lengths[i])
  1234. X        {
  1235. X        if(write_return == -1)
  1236. X        {
  1237. X        perror("Could not write comments to file");
  1238. X        }
  1239. X        else
  1240. X        {
  1241. X        fprintf(stderr,"Something went wrong only could write %d bytes of comment line to file\n",write_return);
  1242. X        }
  1243. X        abort();
  1244. X        }
  1245. X    if(i == comment->number_lines - 1) break;
  1246. X        write_return = write(file,"\n",1);
  1247. X        if(write_return != 1)
  1248. X            {
  1249. X            if(write_return == -1)
  1250. X            {
  1251. X            perror("Could not write comments to file");
  1252. X            }
  1253. X            else
  1254. X            {
  1255. X            fprintf(stderr,"Something went wrong could not write \\n to file\n",write_return);
  1256. X            }
  1257. X            abort();
  1258. X            }
  1259. X    }
  1260. X    }
  1261.  
  1262.  
  1263. X/*
  1264. X    Adds a line to comments;
  1265. X*/
  1266. Xvoid
  1267. Xadd_comment(line,im)
  1268. Xchar *line;
  1269. Ximage_pt im;
  1270. X    {
  1271. X    card length = (card) strlen(line);
  1272. X    char *strcpy();
  1273.  
  1274. X/* 
  1275. X    add in the length of the line and the carriage return 
  1276. X    to the comment length
  1277. X*/
  1278. X    im->head.cv_lcom += (im->head.cv_lcom == 0) ? length : length + 1;
  1279.  
  1280. X/* increment the number of lines */
  1281. X    im->comment.number_lines++;
  1282.  
  1283. X/* allocates space for new line length */
  1284. X    im->comment.line_lengths = (card *) realloc
  1285. X                    (
  1286. X                    (char *) (im->comment.line_lengths),
  1287. X                    (unsigned) (im->comment.number_lines*sizeof(card))
  1288. X                    );
  1289. X/* store new line length */
  1290. X    im->comment.line_lengths[im->comment.number_lines-1] = length;
  1291. X    
  1292. X/* allocates space for ptr to new line */
  1293. X    im->comment.lines = (char **) realloc
  1294. X                    (
  1295. X                    (char *) (im->comment.lines),
  1296. X                    (unsigned) (im->comment.number_lines*sizeof(char *))
  1297. X                    );
  1298.  
  1299. X/* allocates space and copies in new line */
  1300. X    im->comment.lines[im->comment.number_lines-1] = strcpy
  1301. X        (
  1302. X        (char *) MALLOC((length+1)*sizeof(char)),
  1303. X        line
  1304. X        );
  1305. X    }
  1306.  
  1307. X    
  1308. X/*
  1309. X    Appends the comments from one image to the comments of another
  1310. X    im1 has im2's comments appended to it
  1311. X*/
  1312. Xvoid
  1313. Xappend_comments(im1,im2)
  1314. Ximage_pt im1,im2;
  1315. X    {
  1316. X    register card i;
  1317.  
  1318. X/* iterate through the lines of im2 adding them 1 at a time */
  1319. X    for(i = 0 ; i < im2->comment.number_lines ; i++) 
  1320. X    {
  1321. X    add_comment(im2->comment.lines[i],im1);
  1322. X    }
  1323. X    }
  1324.  
  1325. X/*
  1326. X    Prints comments to file
  1327. X*/
  1328. Xvoid
  1329. Xprint_comments(fptr,im)
  1330. XFILE *fptr;
  1331. Ximage_pt im;
  1332. X    {
  1333. X    card numlines = im->comment.number_lines;
  1334. X    register card i;
  1335. X    for(i = 0; i < numlines; i++)
  1336. X    {
  1337. X    fprintf(fptr,"%s\n",im->comment.lines[i]);
  1338. X    }
  1339. X    }
  1340. @//E*O*F varc++/image.c.old//
  1341. chmod u=rw,g=r,o=r $OUT
  1342.  
  1343. echo x - varc++/double_image.c++
  1344. if test -f varc++/double_image.c++ ; then
  1345.     echo varc++/double_image.c++ exists, putting output in $$varc++/double_image.c++
  1346.     OUT=$$varc++/double_image.c++
  1347.     STATUS=1
  1348. else
  1349.     OUT=varc++/double_image.c++
  1350. fi
  1351. sed 's/^X//' > $OUT <<'@//E*O*F varc++/double_image.c++//'
  1352. X/*
  1353. X    This file contains the routines necessary to manipulate an image
  1354. X    of 8 bit data that do not need to know about the image file format
  1355. X*/
  1356.  
  1357. X#include <stream.h>
  1358. X#include <stdio.h>
  1359.  
  1360. X#include "for.h++"
  1361.  
  1362. X#include "double_image.h++"
  1363.  
  1364.  
  1365. X/* the constructor when the image is built */
  1366. Xdouble_image::double_image 
  1367. X    ( 
  1368. X    const create_image_type cit ,    // marker that the image is being created
  1369. X    const card n_rows ,         // the number of rows in the image
  1370. X    const card n_cols ,         // the number of collumns in the image
  1371. X    const FILE * image_file ,    // file for image
  1372. X    const card w_width = 1 ,    // window width
  1373. X    const card w_length = 1     // window length
  1374. X    )
  1375. X    : ( CREATE , image_file , n_rows , n_cols , w_width , w_length )
  1376. X    {
  1377. X    /* check that the constructor is called correctly */
  1378. X    if ( cit != CREATE )
  1379. X    {
  1380. X    cerr << "constructor for double_image being called in obscure way\n";
  1381. X    abort();
  1382. X    }
  1383. X    
  1384. X    /* allocate space for image */
  1385. X    image_buffer = new double [ n_rows*n_cols ];
  1386.  
  1387. X    /* allocate space for dope vector */
  1388. X    image_rows = new double * [ n_rows ];
  1389. X    /* allocate space for window dope vector */
  1390. X    window_rows = new double * [ w_length ];
  1391.  
  1392. X    /* initialize dope vector */
  1393. X    FOR(int i1 = 0 ; i1 < n_rows; i1++)
  1394. X    {
  1395. X    image_rows[i1] = image_buffer + i1*n_cols;
  1396. X    }
  1397. X    ENDFOR
  1398.  
  1399. X    /* set up the protection  so the image can be written */
  1400. X    prot = CAN_WRITE;
  1401.  
  1402. X    /* initialize function pointers */
  1403. X    next = &uninitialized_next;
  1404. X    prev = &uninitialized_prev;
  1405. X    get_w_e_pointer = &uninitialized_get_w_e;
  1406. X    write_w_e_pointer = &uninitialized_write_w_e;
  1407. X    }
  1408.  
  1409.  
  1410. X/* functions for function pointers */
  1411.  
  1412. X/* this version of next assumes the window has been initialized */
  1413. Xint 
  1414. Xdouble_image::initialized_next ()
  1415. X    {
  1416. X    // if at the end of a row
  1417. X    if ( collumn + window_width == number_cols )
  1418. X    {
  1419. X    // if at the end of the image
  1420. X    if ( row + window_length == number_rows )
  1421. X        {
  1422. X        return 0;
  1423. X        }
  1424. X    // otherwise go to the beginning of the next row
  1425. X    collumn = 0;
  1426. X    row++;
  1427. X    // reset the pointers in the window
  1428. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  1429. X        {
  1430. X        window_rows[i1] = image_rows[row + i1];
  1431. X        }
  1432. X    ENDFOR
  1433. X    // return successfully
  1434. X    return 1;
  1435. X    }
  1436. X    // otherwise move adouble row
  1437. X    collumn++;
  1438. X    // move the pointers in the window
  1439. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  1440. X    {
  1441. X    window_rows[i1]++;
  1442. X    }
  1443. X    ENDFOR
  1444. X    // return successfully
  1445. X    return 1;
  1446. X    }
  1447.  
  1448. X/* this version of prev assumes the window has been initialized */
  1449. Xint 
  1450. Xdouble_image::initialized_prev ()
  1451. X    {
  1452. X    // if at beginning of a row
  1453. X    if ( collumn == 0 )
  1454. X    {
  1455. X    // if at the beginning of the image
  1456. X    if ( row == 0 )
  1457. X        {
  1458. X        return 0;
  1459. X        }
  1460. X    // otherwise go to the end of the previous row
  1461. X    collumn = number_cols - window_width;
  1462. X    row--;
  1463. X    // reset the pointers in the window
  1464. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  1465. X        {
  1466. X        window_rows[i1] = image_rows[row + i1] + collumn;
  1467. X        }
  1468. X    ENDFOR
  1469. X    // return successfully
  1470. X    return 1;
  1471. X    }
  1472. X    // otherwise move back on the row
  1473. X    collumn--;
  1474. X    // move the pointers in the window
  1475. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  1476. X    {
  1477. X    window_rows[i1]--;
  1478. X    }
  1479. X    ENDFOR
  1480. X    // return successfully
  1481. X    return 1;
  1482. X    }
  1483.  
  1484. X/* this version of next initializes the window */
  1485. Xint 
  1486. Xdouble_image::uninitialized_next ()
  1487. X    {
  1488. X    // check that the window fits in the image
  1489. X    if ( (window_width > number_cols) || (window_length > number_rows) )
  1490. X    {
  1491. X    return 0;
  1492. X    }
  1493.  
  1494. X    // set row and collumn to 0
  1495. X    row = 0;
  1496. X    collumn = 0;
  1497.  
  1498. X    // set the window row pointers
  1499. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  1500. X    {
  1501. X    window_rows[i1] = image_rows[row + i1];
  1502. X    }
  1503. X    ENDFOR
  1504.  
  1505. X    // set the function pointers
  1506. X    next = &initialized_next;
  1507. X    prev = &initialized_prev;
  1508. X    get_w_e_pointer = &initialized_get_w_e;
  1509. X    write_w_e_pointer = &initialized_write_w_e;
  1510.  
  1511. X    // set the window status
  1512. X    window_status = INITIALIZED;
  1513. X    return 1;
  1514. X    }
  1515.  
  1516. X/* this version of prev initializes the window */
  1517. Xint 
  1518. Xdouble_image::uninitialized_prev ()
  1519. X    {
  1520. X    // check that the window fits in the image
  1521. X    if ( (window_width > number_cols) || (window_length > number_rows) )
  1522. X    {
  1523. X    return 0;
  1524. X    }
  1525.  
  1526. X    // set row and collumn to bottom right of image
  1527. X    row = number_rows - window_length;
  1528. X    collumn = number_cols - window_width;
  1529. X    // set the window row pointers
  1530. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  1531. X    {
  1532. X    window_rows[i1] = image_rows[row + i1] + collumn;
  1533. X    }
  1534. X    ENDFOR
  1535.  
  1536. X    // set the function pointers
  1537. X    next = &initialized_next;
  1538. X    prev = &initialized_prev;
  1539. X    get_w_e_pointer = &initialized_get_w_e;
  1540. X    write_w_e_pointer = &initialized_write_w_e;
  1541.  
  1542. X    // set the window status
  1543. X    window_status = INITIALIZED;
  1544. X    return 1;
  1545. X    }
  1546.  
  1547. X// this version of next says that applying the next operation is impossible
  1548. Xint
  1549. Xdouble_image::impossible_next ( )
  1550. X    {
  1551. X    cerr << "Trying to apply the next operation to an image for which it is impossible!\n";
  1552. X    return 0;
  1553. X    }
  1554.  
  1555. X// this version of prev says that applying the next operation is impossible
  1556. Xint
  1557. Xdouble_image::impossible_prev ( )
  1558. X    {
  1559. X    cerr << "Trying to apply the prev operation to an image for which it is impossible!\n";
  1560. X    return 0;
  1561. X    }
  1562.  
  1563. X/* uninitialized version of get_w_e will just die */
  1564. Xdouble 
  1565. Xdouble_image::uninitialized_get_w_e ( const card i , const card j )
  1566. X    {
  1567. X    cerr << "Trying to get an element of an uninitialized window\n";
  1568. X    cerr << "The element was " << i << "," << j << "\n";
  1569. X    abort ();
  1570. X    return 0;
  1571. X    }
  1572.  
  1573.  
  1574. X/* initialized version of get_w_e */
  1575. Xdouble 
  1576. Xdouble_image::initialized_get_w_e ( const card i , const card j )
  1577. X    {
  1578. X    // check that i,j is in the window
  1579. X    if ( ( i >= window_length ) || ( j >= window_width ) )
  1580. X    {
  1581. X    cerr << "Tried to access element outside window\n";
  1582. X    cerr << "Window size " << window_length << "," << window_width << "\n";
  1583. X    cerr << "Accessed " << i << "," << j << "\n";
  1584. X    abort ();
  1585. X    return 0;
  1586. X    }
  1587. X    
  1588. X    // otherwise return the element
  1589. X    return window_rows[i][j];
  1590. X    }
  1591.  
  1592. X/* uninitialized version of write_w_e will just die */
  1593. Xvoid 
  1594. Xdouble_image::uninitialized_write_w_e ( const card i , const card j , const double value )
  1595. X    {
  1596. X    cerr << "Trying to write to an element of an uninitialized window\n";
  1597. X    cerr << "Trying to write " << value << "\n";
  1598. X    cerr << "To " << i << "," << j << "\n";
  1599. X    abort ();
  1600. X    }
  1601.  
  1602. X/* initialized version of write_w_e */
  1603. Xvoid 
  1604. Xdouble_image::initialized_write_w_e ( const card i , const card j , const double value)
  1605. X    {
  1606. X    // check that i,j is in the window
  1607. X    if ( ( i >= window_length ) || ( j >= window_width ) )
  1608. X    {
  1609. X    cerr << "Tried to access element outside window\n";
  1610. X    cerr << "Window size " << window_length << "," << window_width << "\n";
  1611. X    cerr << "Accessed " << i << "," << j << "\n";
  1612. X    abort ();
  1613. X    }
  1614. X    
  1615. X    // otherwise set the element
  1616. X    window_rows[i][j] = value;
  1617. X    }
  1618.  
  1619. X/*
  1620. X    move in row n steps 
  1621. X    returns 1 when that motion is legal 0 otherwise
  1622. X*/
  1623. Xint 
  1624. Xdouble_image::move_collumn ( const int n ) 
  1625. X    {
  1626. X    // the version in image does the checking and most of the work
  1627. X    int result = image_class::move_collumn ( n );
  1628.  
  1629. X    // if the move was successful move the window
  1630. X    if ( result == 1 )
  1631. X    {
  1632. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  1633. X        {
  1634. X        window_rows[i1] += n;
  1635. X        }
  1636. X    ENDFOR
  1637. X    }
  1638.  
  1639. X    return result;
  1640. X    }
  1641.  
  1642. X/*
  1643. X    move in collumn n steps
  1644. X    returns 1 when that motion is legal 0 otherwise
  1645. X*/
  1646. Xint 
  1647. Xdouble_image::move_row ( const int n ) 
  1648. X    {
  1649. X    // the version in image does the checking and most of the work
  1650. X    int result = image_class::move_row ( n );
  1651.  
  1652. X    // if the move was successful move the window
  1653. X    if ( result == 1 )
  1654. X    {
  1655. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  1656. X        {
  1657. X        window_rows[i1] = image_rows[row + i1] + collumn ;
  1658. X        }
  1659. X    ENDFOR
  1660. X    }
  1661.  
  1662. X    return result;
  1663. X    }
  1664.  
  1665.  
  1666. X/*
  1667. X    move to specified row
  1668. X*/
  1669. Xvoid 
  1670. Xdouble_image::move_to_row ( const card n ) 
  1671. X    {
  1672. X    // the version in image does the checking and most of the work
  1673. X    image_class::move_to_row ( n );
  1674.  
  1675. X    // move the window to the specified place
  1676. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  1677. X    {
  1678. X    window_rows[i1] = image_rows[row + i1] + collumn ;
  1679. X    }
  1680. X    ENDFOR
  1681. X    }
  1682.  
  1683.  
  1684. X/*
  1685. X    move to specified collumn
  1686. X*/
  1687. Xvoid 
  1688. Xdouble_image::move_to_collumn ( const card n ) 
  1689. X    {
  1690. X    // the version in image does the checking and most of the work
  1691. X    image_class::move_to_collumn ( n );
  1692.  
  1693. X    // move the window to the specified place
  1694. X    FOR(int i1 = 0 ; i1 < window_length ; i1++)
  1695. X    {
  1696. X    window_rows[i1] = image_rows[row + i1] + collumn ;
  1697. X    }
  1698. X    ENDFOR
  1699. X    }
  1700.  
  1701.  
  1702.  
  1703. X/*
  1704. X    Gets a pointer to a row
  1705. X    of the image
  1706. X*/
  1707. Xconst double * 
  1708. Xdouble_image::get_row( card row )
  1709. X    {
  1710. X    // Checks to make sure request is legal
  1711. X    if ( row >= number_rows )
  1712. X    {
  1713. X    cerr << "Tried to accesses row " << row;
  1714. X    cerr << " when image only has " << number_rows << " rows!\n";
  1715. X    abort();
  1716. X    }
  1717. X    if ( image_status == UNINITIALIZED )
  1718. X    {
  1719. X    cerr << "Trying to read row from unitialized image!\n";
  1720. X    abort();
  1721. X    }
  1722. X    if ( (prot != CAN_READ) && (prot != CAN_READ_AND_WRITE) )
  1723. X    {
  1724. X    cerr << "Trying to access a row of an image protected against reading!\n";
  1725. X    abort();
  1726. X    }
  1727. X    
  1728. X    return image_rows[row];
  1729. X    }
  1730.  
  1731. X/*
  1732. X    Change the size of a window
  1733. X    causes the window to become uninitialized
  1734. X*/
  1735. Xvoid 
  1736. Xdouble_image::resize_window ( card width , card length )
  1737. X    {
  1738.  
  1739. X    // set the window
  1740. X    window_width = width;
  1741. X    window_length = length;
  1742. X    window_status = UNINITIALIZED;
  1743.  
  1744. X    /* allocate space for window dope vector */
  1745. X    window_rows = new double * [ window_length ];
  1746.  
  1747. X    /* reset function pointers */
  1748. X    next = &uninitialized_next;
  1749. X    prev = &uninitialized_prev;
  1750. X    get_w_e_pointer = &uninitialized_get_w_e;
  1751. X    write_w_e_pointer = &uninitialized_write_w_e;
  1752. X    }
  1753.  
  1754. X/*
  1755. X    Causes the window to cover the entire image.
  1756. X    Allows one to access any part of the image with window operations
  1757. X*/
  1758. Xvoid 
  1759. Xdouble_image::window_entire_image ( )
  1760. X    {
  1761. X    // set up the window
  1762. X    window_width = number_cols;
  1763. X    window_length = number_rows;
  1764. X    window_status = INITIALIZED;
  1765. X    // make the window dope vector an alias for the image dope vector
  1766. X    window_rows = image_rows;
  1767.  
  1768. X    // set up function pointers so next and previous impossible
  1769. X    next = &impossible_next;
  1770. X    prev = &impossible_prev;
  1771. X    // access functions
  1772. X    get_w_e_pointer = &initialized_get_w_e;
  1773. X    write_w_e_pointer = &initialized_write_w_e;
  1774. X    }
  1775. X/*
  1776. XCopyright (C) 1986, David Sher in the University of Rochester
  1777. XPermission is granted to any individual or institution to use, copy, or
  1778. Xredistribute this software so long as it is not sold for profit, provided
  1779. Xthis copyright notice is retained.
  1780. X*/
  1781. @//E*O*F varc++/double_image.c++//
  1782. chmod u=rw,g=r,o=r $OUT
  1783.  
  1784. echo x - vartools/trunc.c++
  1785. if test -f vartools/trunc.c++ ; then
  1786.     echo vartools/trunc.c++ exists, putting output in $$vartools/trunc.c++
  1787.     OUT=$$vartools/trunc.c++
  1788.     STATUS=1
  1789. else
  1790.     OUT=vartools/trunc.c++
  1791. fi
  1792. sed 's/^X//' > $OUT <<'@//E*O*F vartools/trunc.c++//'
  1793. X/*
  1794. X    This is the routine that takes in a double image and truncates
  1795. X    it to a long image
  1796. X*/
  1797. X#include <stdio.h>
  1798. X#include <string.h>
  1799. X#include <long_image.h++>
  1800. X#include <double_image.h++>
  1801. X#include "vartools.h++"
  1802.  
  1803. X/*
  1804. X    Truncates an input image needs a file to be output to
  1805. X    but does not write to file
  1806. X*/
  1807. Xlong_image&
  1808. Xtrunc2( double_image& input , FILE *outfile )
  1809. X    {
  1810. X    long_image *output_p = new long_image(CREATE,input.n_rows(),input.n_cols(),outfile);
  1811. X    long_image& output = *output_p;
  1812. X    while(++input,++output)
  1813. X    {
  1814. X    output() = input();
  1815. X    }
  1816. X    return output;
  1817. X    }
  1818.  
  1819.  
  1820. X/*
  1821. X    Takes two files and reads from one to write to the other
  1822. X*/
  1823. Xvoid
  1824. Xtrunc( FILE *infile , FILE *outfile, char *comment)
  1825. X    {
  1826. X    double_image input(READ,infile);
  1827. X    long_image& output = trunc2(input,outfile);
  1828. X    output.set_comments(comment,strlen(comment));
  1829. X    output.add_comment("The file being truncated is:\n",strlen("The file being truncated is:\n"));
  1830. X    output.add_comment((char *) input.the_comments(),input.c_length());
  1831. X    output.write();
  1832. X    }
  1833. X/*
  1834. XCopyright (C) 1986, David Sher in the University of Rochester
  1835. XPermission is granted to any individual or institution to use, copy, or
  1836. Xredistribute this software so long as it is not sold for profit, provided
  1837. Xthis copyright notice is retained.
  1838. X*/
  1839. @//E*O*F vartools/trunc.c++//
  1840. chmod u=rw,g=r,o=r $OUT
  1841.  
  1842. echo x - vartools/scale.c++
  1843. if test -f vartools/scale.c++ ; then
  1844.     echo vartools/scale.c++ exists, putting output in $$vartools/scale.c++
  1845.     OUT=$$vartools/scale.c++
  1846.     STATUS=1
  1847. else
  1848.     OUT=vartools/scale.c++
  1849. fi
  1850. sed 's/^X//' > $OUT <<'@//E*O*F vartools/scale.c++//'
  1851.  
  1852. X/*
  1853. X    This file contains the declarations necessary to scale 
  1854. X    the pixels in images.
  1855. X*/
  1856.  
  1857. X#include <stream.h>
  1858. X#include <stdio.h>
  1859. X#include <string.h>
  1860. X#include <double_image.h++>
  1861. X#include "vartools.h++"
  1862.  
  1863. X/*
  1864. X    This takes an image as input and create another
  1865. X*/
  1866. Xdouble_image&
  1867. Xscale2(double scale, double increment, double_image& input, FILE *output_file)
  1868. X    {
  1869. X    // create the output image 
  1870. X    double_image *output_pointer = 
  1871. X    new double_image(CREATE,input.n_rows(),input.n_cols(),output_file);
  1872. X    double_image& output = *output_pointer;
  1873.  
  1874. X    // scale  and increment the image
  1875. X    while(input++,output++)
  1876. X    {
  1877. X    output() = input() * scale + increment;
  1878. X    }
  1879. X    
  1880. X    return output;
  1881. X    }
  1882.  
  1883. X/*
  1884. X    This takes two files and takes one and puts a scaled version into the other
  1885. X*/
  1886. Xvoid
  1887. Xscale(double scale, double increment, FILE *input, FILE *output, char * comment)
  1888. X    {
  1889. X    // read in the input image
  1890. X    double_image input_image(READ,input);
  1891. X    // scale and  increment it
  1892. X    double_image& output_image = scale2(scale,increment,input_image,output);
  1893. X    // set up the comments
  1894. X    output_image.set_comments(comment,strlen(comment));
  1895. X    // add the comments 
  1896. X    char *string = 
  1897. X    form("Scaling image: scale %lf increment %lf\n",scale,increment);
  1898. X    output_image.add_comment(string,strlen(string));
  1899. X    output_image.add_comment((char *) input_image.the_comments(),input_image.c_length());
  1900.  
  1901. X    // output the image to file
  1902. X    output_image.write();
  1903. X    }
  1904. X/*
  1905. XCopyright (C) 1986, David Sher in the University of Rochester
  1906. XPermission is granted to any individual or institution to use, copy, or
  1907. Xredistribute this software so long as it is not sold for profit, provided
  1908. Xthis copyright notice is retained.
  1909. X*/
  1910. @//E*O*F vartools/scale.c++//
  1911. chmod u=rw,g=r,o=r $OUT
  1912.  
  1913. echo x - vartools/correlate.c++
  1914. if test -f vartools/correlate.c++ ; then
  1915.     echo vartools/correlate.c++ exists, putting output in $$vartools/correlate.c++
  1916.     OUT=$$vartools/correlate.c++
  1917.     STATUS=1
  1918. else
  1919.     OUT=vartools/correlate.c++
  1920. fi
  1921. sed 's/^X//' > $OUT <<'@//E*O*F vartools/correlate.c++//'
  1922. X/*
  1923. X    This is the source file for correlation routines
  1924. X*/
  1925.  
  1926. X#include <stream.h>
  1927. X#include <stdio.h>
  1928. X#include <string.h>
  1929. X#include <for.h++>
  1930. X#include <double_image.h++>
  1931. X#include "vartools.h++"
  1932.  
  1933. X// this routine correlates the image at a point
  1934. Xdouble
  1935. Xdo_correlate(double_image& template, double_image& input)
  1936. X    {
  1937. X    // total sums up the correlation
  1938. X    double total = 0.;
  1939.  
  1940. X    // iterate through the template
  1941. X    FOR(int i1 = 0 ; i1 < template.n_rows() ; i1++)
  1942. X    {
  1943. X    FOR(int i2 = 0 ; i2 < template.n_cols() ; i2++)
  1944. X        {
  1945. X        total += template.get_w_e(i1,i2)*input.get_w_e(i1,i2);
  1946. X        }
  1947. X    ENDFOR
  1948. X    }
  1949. X    ENDFOR
  1950.  
  1951. X    return total;
  1952. X    }
  1953.  
  1954. X// this one takes 2 images and returns an image containing the correlation
  1955. Xdouble_image&
  1956. Xcorrelate2(double_image& template, double_image& input, FILE *output_file)
  1957. X    {
  1958. X    // check that the template is smaller than the input
  1959. X    if 
  1960. X    ( 
  1961. X    (template.n_rows() > input.n_rows()) 
  1962. X    || 
  1963. X    (template.n_cols() > input.n_cols()) 
  1964. X    )
  1965. X    {
  1966. X    cerr << form
  1967. X        (
  1968. X        "Template[%d,%d] is larger than image[%d,%d]!\n",
  1969. X        template.n_rows(),
  1970. X        template.n_cols(),
  1971. X        input.n_rows(),
  1972. X        input.n_cols(),
  1973. X        );
  1974. X    abort();
  1975. X    }
  1976. X    // the output will only have points of the input that
  1977. X    // can be completely calculated (template does not fall off edge)
  1978. X    double_image *output_pointer = new double_image
  1979. X    (
  1980. X    CREATE,
  1981. X    input.n_rows() - template.n_rows() + 1,
  1982. X    input.n_cols() - template.n_cols() + 1,
  1983. X    output_file
  1984. X    );
  1985. X    double_image& output = *output_pointer;
  1986. X    
  1987. X    // make sure the window size is the same as the template size
  1988. X    // for the input
  1989. X    input.resize_window(template.n_cols(),template.n_rows());
  1990.  
  1991. X    // make the entire template random accessable
  1992. X    template.window_entire_image();
  1993.  
  1994. X    // iterate through image correlating
  1995. X    while(++input,++output)
  1996. X    {
  1997. X    output() = do_correlate(template,input);
  1998. X    }
  1999. X    
  2000. X    // return the output image
  2001. X    return output;
  2002. X    }
  2003.  
  2004. X// this one takes 3 file pointers
  2005. Xvoid
  2006. Xcorrelate(FILE *template_file, FILE *input_file, FILE *output_file, char *comment)
  2007. X    {
  2008. X    // read in the template and input file
  2009. X    double_image template(READ,template_file);
  2010. X    double_image input(READ,input_file);
  2011.  
  2012. X    // do the correlation
  2013. X    double_image& output = correlate2(template,input,output_file);
  2014.  
  2015. X    // construct the comments
  2016. X    output.set_comments(comment,strlen(comment));
  2017. X    output.add_comment("Engaged in correlation, template is:\n",strlen("Engaged in correlation, template is:\n"));
  2018. X    output.add_comment((char *) template.the_comments(), template.c_length());
  2019. X    output.add_comment("\nImage is:\n",strlen("\nImage is:\n"));
  2020. X    output.add_comment((char *) input.the_comments(), input.c_length());
  2021.  
  2022. X    // write the image to file
  2023. X    output.write();
  2024. X    }
  2025. X/*
  2026. XCopyright (C) 1986, David Sher in the University of Rochester
  2027. XPermission is granted to any individual or institution to use, copy, or
  2028. Xredistribute this software so long as it is not sold for profit, provided
  2029. Xthis copyright notice is retained.
  2030. X*/
  2031. @//E*O*F vartools/correlate.c++//
  2032. chmod u=rw,g=r,o=r $OUT
  2033.  
  2034. echo Inspecting for damage in transit...
  2035. temp=/tmp/sharin$$; dtemp=/tmp/sharout$$
  2036. trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
  2037. cat > $temp <<\!!!
  2038.      426    1682   10472 long_image.c++
  2039.      286    1115    6652 image.c++
  2040.      567    1631   12970 image.c.old
  2041.      429    1682   10537 double_image.c++
  2042.       46     162    1291 trunc.c++
  2043.       59     198    1700 scale.c++
  2044.      109     344    2977 correlate.c++
  2045.     1922    6814   46599 total
  2046. !!!
  2047. wc  varc++/long_image.c++ varc++/image.c++ varc++/image.c.old varc++/double_image.c++ vartools/trunc.c++ vartools/scale.c++ vartools/correlate.c++ | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
  2048. if test -s $dtemp ; then
  2049.     echo "Ouch [diff of wc output]:"
  2050.     cat $dtemp
  2051.     STATUS=1
  2052. elif test $STATUS = 0 ; then
  2053.     echo "No problems found."
  2054. else
  2055.     echo "WARNING -- PROBLEMS WERE FOUND..."
  2056. fi
  2057. exit $STATUS
  2058.