home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v941.tgz / icon.v941src.tar / icon.v941src / ipl / gprocs / imrutils.icn < prev    next >
Text File  |  2002-01-24  |  7KB  |  333 lines

  1. ############################################################################
  2. #
  3. #    File:     imrutils.icn
  4. #
  5. #    Subject:  Procedures to deal with image records
  6. #
  7. #    Author:   Ralph E. Griswold
  8. #
  9. #    Date:     January 23, 2002
  10. #
  11. ############################################################################
  12. #
  13. #  This file is in the public domain.
  14. #
  15. ############################################################################
  16. #
  17. #  Procedures to manipulate image strings as records.  
  18. #
  19. #    imrcath(imr1, imr2)
  20. #            concatenates imr1 and imr2 horizontally
  21. #
  22. #    imrcatv(imr1, imr2)
  23. #            concatenates imr1 and imr2 vertically
  24. #
  25. #    imrcopy(imr)    create copy of imr
  26. #
  27. #    imrdraw(win, x, y, imr)
  28. #            draws an image record
  29. #
  30. #    imrfliph(imr)    flips an image record horizontally
  31. #
  32. #    imrflipv(imr)    flips an image record vertically
  33. #
  34. #    imrnegative(imr)
  35. #            produces "negative" of image; intended for
  36. #            grayscale palettes
  37. #
  38. #    imropen(imr)    opens a hidden window with an image record
  39. #
  40. #    imror(imr)    forms inclusive "or" of two images
  41. #
  42. #    imrpshift(imr, ir)
  43. #            shifts colors by mapping rotated palette
  44. #
  45. #    imrrot180(imr)
  46. #            rotates an image record 180 degrees
  47. #
  48. #    imrrot90cw(imr)
  49. #            rotates an image record 90 degrees clockwise
  50. #
  51. #    imrshifth(imr, i)
  52. #            shifts an image record horizontally by i pixels
  53. #            with wrap-around; positive i to the right,
  54. #            negative to the left.
  55. #
  56. #    imrshiftv(imr, i)
  57. #            shifts an image record vertically by i pixels
  58. #            with wrap-around; positive i to the top,
  59. #            negative to the bottom.
  60. #
  61. #    imstoimr(s)    converts an image string to an image record
  62. #
  63. #    imrtoims(imr)    converts an image record to an image string
  64. #
  65. #  Note:  All the procedures that produce image records modify their
  66. #  argument records; they do not return modified copies.
  67. #
  68. ############################################################################
  69. #
  70. #  Possible additions:
  71. #
  72. #    Make stripes from one (or more) rows/columns.
  73. #
  74. #    Convert from one palette to another.
  75. #
  76. ############################################################################
  77. #
  78. #  Requires:  Version 9 graphics  
  79. #
  80. ############################################################################
  81. #
  82. #  Links:  strings, wopen
  83. #
  84. ############################################################################
  85.  
  86. link strings
  87. link wopen
  88.  
  89. record ImageRecord(width, palette, pixels)
  90.  
  91. procedure imrcath(imr1, imr2)    #: horizontally concatenate image records
  92.    local imr, i, rows1, rows2
  93.  
  94.    if *imr1.pixels / imr1.width ~= *imr2.pixels / imr2.width then fail
  95.    if imr1.palette ~== imr2.palette then fail
  96.  
  97.    imr := ImageRecord()
  98.    imr.width := imr1.width + imr2.width
  99.    imr.palette := imr1.palette
  100.  
  101.    rows1 := []
  102.  
  103.    imr1.pixels ? {
  104.       while put(rows1, move(imr1.width))
  105.       }
  106.  
  107.    rows2 := []
  108.  
  109.    imr2.pixels ? {
  110.       while put(rows2, move(imr2.width))
  111.       }
  112.  
  113.    imr.pixels := ""
  114.  
  115.    every i := 1 to *rows1 do
  116.       imr.pixels ||:= rows1[i] || rows2[i]
  117.  
  118.    return imr
  119.  
  120. end
  121.  
  122. procedure imrcatv(imr1, imr2)        #: vertically concatenate image records
  123.    local imr
  124.  
  125.    if imr1.width ~= imr2.width then fail
  126.    if imr1.palette ~== imr2.palette then fail
  127.  
  128.    imr := ImageRecord()
  129.    imr.width := imr1.width
  130.    imr.palette := imr1.palette        # CHECK
  131.    imr.pixels := imr1.pixels || imr2.pixels
  132.  
  133.    return imr
  134.  
  135. end
  136.  
  137. procedure imrcopy(imr)
  138.  
  139.    return copy(imr)
  140.  
  141. end
  142.  
  143. procedure imrdraw(win, x, y, imr)    #: draw image record
  144.  
  145.    if type(win) ~== "window" then {
  146.       win :=: x :=: y :=: imr
  147.       win := \&window | runerr(140, &window)
  148.       }
  149.  
  150.    /x := 0
  151.    /y := 0
  152.  
  153.    return DrawImage(win, x, y, imrtoims(imr))
  154.  
  155. end
  156.  
  157. procedure imrflipd(imr)            #: flip image record diagonally
  158.    local height, columns, i, row
  159.  
  160.    height := *imr.pixels / imr.width
  161.    columns := list(height, "")
  162.  
  163.    imr.pixels ? {
  164.       while row := move(imr.width) do
  165.          every i := 1 to imr.width do
  166.             columns[i] ||:= row[i]
  167.       }
  168.  
  169.    imr.pixels := ""
  170.  
  171.    every imr.pixels ||:= !columns
  172.  
  173.    imr.width := height
  174.  
  175.    return imr
  176.  
  177. end
  178.  
  179. procedure imrfliph(imr)            #: flip image record horizontally
  180.    local pixels
  181.  
  182.    pixels := ""
  183.  
  184.    imr.pixels ? {
  185.       while pixels ||:= reverse(move(imr.width))
  186.       }
  187.  
  188.    imr.pixels := pixels
  189.  
  190.    return imr
  191.  
  192. end
  193.  
  194. procedure imrflipv(imr)            #: flip image record vertically
  195.    local pixels
  196.  
  197.    pixels := ""
  198.  
  199.    imr.pixels ? {
  200.       while pixels := move(imr.width) || pixels
  201.       }
  202.  
  203.    imr.pixels := pixels
  204.  
  205.    return imr
  206.  
  207. end
  208.  
  209. procedure imrnegative(imr)        #: form negative of image record
  210.    local chars
  211.  
  212.    chars := PaletteChars(imr.palette)
  213.  
  214.    imr.pixels := map(imr.pixels, chars, reverse(chars))
  215.  
  216.    return imr
  217.  
  218. end
  219.  
  220. procedure imropen(imr)            #: open window with image record
  221.    local win
  222.  
  223.    win := WOpen("canvas=hidden","size=" || imr.width || "," ||
  224.       *imr.pixels / imr.width)
  225.  
  226.    imrdraw(win, 0, 0, imr) | {
  227.       WClose(win)
  228.       fail
  229.       }
  230.  
  231.    return win
  232.    
  233. end
  234.  
  235. procedure imrpshift(imr, i)        #: map shifted palette
  236.    local chars
  237.  
  238.    chars := PaletteChars(imr.palette)
  239.  
  240.    imr.pixels := map(imr.pixels, chars, rotate(chars, i))
  241.  
  242.    return imr
  243.  
  244. end
  245.  
  246. procedure imrrot180(imr)        #: rotate image record 180 degrees
  247.  
  248.    imr.pixels := reverse(imr.pixels)
  249.  
  250.    return imr
  251.  
  252. end
  253.  
  254. procedure imrrot90cw(imr)        #: rotate image record 90 deg. clockwise
  255.    local height, columns, i, row
  256.  
  257.    height := *imr.pixels / imr.width
  258.    columns := list(imr.width, "")
  259.  
  260.    imr.pixels ? {
  261.       while row := move(imr.width) do
  262.          every i := 1 to imr.width do
  263.             columns[i] := row[i] || columns[i]
  264.       }
  265.  
  266.    imr.pixels := ""
  267.  
  268.    every imr.pixels ||:= !columns
  269.  
  270.    imr.width := height
  271.  
  272.    return imr
  273.  
  274. end
  275.  
  276. #  Note:  Since shifted out pixels enter in the top or bottom row, depending
  277. #  on the direction of the shift, one full pass over the width raises the
  278. #  image one pixel.
  279.  
  280. procedure imrshifth(imr, i)        #: shift image record horizontally
  281.  
  282.    imr.pixels := rotate(imr.pixels, i)
  283.  
  284.    return imr
  285.  
  286. end
  287.  
  288. #  See note on imrshifth()
  289.  
  290. procedure imrshiftv(imr, i)        #: shift image record vertically
  291.  
  292.    /i := 1
  293.  
  294.    imr.pixels := rotate(imr.pixels, i * imr.width)
  295.  
  296.    return imr
  297.  
  298. end
  299.  
  300. procedure imrtoims(imr)            #: convert image record to image string
  301.  
  302.    return imr.width || "," || imr.palette || "," || imr.pixels
  303.  
  304. end
  305.  
  306. procedure imstoimr(s)            #: convert image string to image record
  307.    local imr
  308.  
  309.    imr := ImageRecord()
  310.  
  311.    s ? {
  312.       imr.width := tab(upto(',')) | fail
  313.       move(1)
  314.       imr.palette := tab(upto(',')) | fail
  315.       move(1)
  316.       imr.pixels := tab(0)
  317.       }
  318.  
  319.    return imr
  320.  
  321. end
  322.  
  323. procedure imror(imr)            #: form inclusive "or" of two images
  324.    local chars
  325.  
  326.    chars := PaletteChars(imr.palette)
  327.  
  328.    imr.pixels := map(imr.pixels, chars, reverse(chars))
  329.  
  330.    return imr
  331.  
  332. end
  333.