; tmp.grovel --- вспомогательный файл в синтаксисе cffi-grovel, определяющий константы из glibc
(in-package :system)
(include "sys/types.h"
"sys/stat.h"
"fcntl.h")
(ctype size "size_t")
(ctype ssize "ssize_t")
(cenum open-flags
((:read-only "O_RDONLY"))
((:write-only "O_WRONLY"))
((:create "O_CREAT")))
; основной файл
(let* (; считаем файл
(image (make-instance 'image :width 5 :height 5 :filename #p"data.dat"))
; посчитаем подходящий размер гистограммы найди максимальный размер
; элемента в массиве. Думаю, в реальной задаче он уже известен их других
; соображений
(max (iter
(with data = (data image))
(for i from 0 below (* (width image) (height image)))
(maximize (cffi:mem-aref data :uint32 i))))
; создадим три гистограммы
(hist-red #1=(make-array (1+ max) :element-type 'fixnum :initial-element 0))
(hist-green #1#)
(hist-blue #1#))
(flet (; объявим функцию, возвращающую замыкание, увеличивающее значение в
; соответствующей гистограмме. Интерфейс замыкания подходит для
; использования в качестве параметра map-red, map-green и map-blue
(collect-hist (hist)
(lambda (x y value)
(declare (ignore x y))
(incf (aref hist value)))))
; собираем данные из массива
(map-red (collect-hist hist-red) image)
(map-green (collect-hist hist-green) image)
(map-blue (collect-hist hist-blue) image))
; записываем результат в файл "histograms"
(with-open-file (f #p"histograms" :direction :output :if-exists :supersede)
(format f "~10t ~10@a ~10@a ~10@a~%" "red" "green" "blue")
(iter
(for i from 0 to max)
(for red in-vector hist-red)
(for green in-vector hist-green)
(for blue in-vector hist-blue)
(format f "~10d ~10d ~10d ~10d~%" i red green blue))))
Add a code snippet to your website: www.paste.org