write-image-util.scm 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, David Frese, Mike Sperber
  3. ; Utilities for writing images.
  4. ; The page character is used to mark the ends of the user and prelude sections
  5. ; of image files.
  6. (define *status* (enum errors no-errors))
  7. (define (image-write-status)
  8. *status*)
  9. (define-syntax write-check
  10. (syntax-rules ()
  11. ((write-check exp)
  12. (if (eq? *status* (enum errors no-errors))
  13. (set! *status* exp)))))
  14. (define image-buffer-size 4096)
  15. (define *image-port*)
  16. (define *image-buffer*)
  17. (define *image-buffer-pointer*)
  18. (define (write-header-integer n)
  19. (write-check (write-integer n *image-port*))
  20. (write-check (write-char #\newline *image-port*)))
  21. (define page-character (ascii->char 12))
  22. (define (write-page)
  23. (write-check (write-char page-character *image-port*)))
  24. (define (buffer-contents)
  25. (address-difference *image-buffer-pointer*
  26. *image-buffer*))
  27. (define (image-write-init port)
  28. (set! *image-port* port)
  29. (set! *image-buffer* (allocate-memory image-buffer-size))
  30. (set! *image-buffer-pointer* *image-buffer*)
  31. (set! *status* (enum errors no-errors))
  32. (not (null-address? *image-buffer*)))
  33. (define (image-write-terminate)
  34. (deallocate-memory *image-buffer*))
  35. ; Writing buffers.
  36. (define (write-descriptor descriptor)
  37. (word-set! *image-buffer-pointer* descriptor)
  38. (set! *image-buffer-pointer* (address1+ *image-buffer-pointer*))
  39. (maybe-empty-image-buffer))
  40. (define (write-image-block start size)
  41. (let ((available (- image-buffer-size (buffer-contents))))
  42. (cond ((<= size available)
  43. (copy-image-data start size))
  44. ((<= size image-buffer-size)
  45. (copy-image-data start available)
  46. (copy-image-data (address+ start available) (- size available)))
  47. (else
  48. (empty-image-buffer!)
  49. (write-check (write-block *image-port* start size))))
  50. (unspecific)))
  51. (define (copy-image-data start size)
  52. (copy-memory! start *image-buffer-pointer* size)
  53. (set! *image-buffer-pointer* (address+ *image-buffer-pointer* size))
  54. (maybe-empty-image-buffer))
  55. (define (maybe-empty-image-buffer)
  56. (if (= (buffer-contents)
  57. image-buffer-size)
  58. (empty-image-buffer!)))
  59. (define (empty-image-buffer!)
  60. (let ((have (buffer-contents)))
  61. (cond ((< 0 have)
  62. (write-check (write-block *image-port* *image-buffer* have))
  63. (set! *image-buffer-pointer* *image-buffer*)))))