Compare commits
3 Commits
c6e5bd376c
...
73e975dd59
Author | SHA1 | Date |
---|---|---|
randomuser | 73e975dd59 | |
randomuser | 2fb96d41e8 | |
randomuser | fbdd82c587 |
|
@ -35,8 +35,5 @@ OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
For more information, please refer to <http://unlicense.org/>
|
For more information, please refer to <http://unlicense.org/>
|
||||||
|
|
||||||
## trivial technology
|
|
||||||
archival should be available for everyone, and the systems behind this project should be easy to understand, so it's trivial technology. see <gemini://inixj-ix.luxe/wiki/trivial-technology--landing/>.
|
|
||||||
|
|
||||||
## contact
|
## contact
|
||||||
randomuser at tilde dot club
|
randomuser at tilde dot club
|
||||||
|
|
137
sane_hello.c
137
sane_hello.c
|
@ -1,137 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <sane/sane.h>
|
|
||||||
#include <png.h>
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t red;
|
|
||||||
uint8_t green;
|
|
||||||
uint8_t blue;
|
|
||||||
} pixel_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
pixel_t *pixels;
|
|
||||||
size_t width;
|
|
||||||
size_t height;
|
|
||||||
} bitmap_t;
|
|
||||||
|
|
||||||
pixel_t *pixel_at(bitmap_t * bitmap, int x, int y) {
|
|
||||||
return bitmap->pixels + bitmap->width * y + x;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pngtofile(bitmap_t *bitmap, FILE *fp) {
|
|
||||||
png_structp png_ptr = NULL;
|
|
||||||
png_infop info_ptr = NULL;
|
|
||||||
size_t x, y;
|
|
||||||
png_byte **row_pointers = NULL;
|
|
||||||
|
|
||||||
int status = -1;
|
|
||||||
int pixel_size = 3;
|
|
||||||
int depth = 8;
|
|
||||||
|
|
||||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
|
||||||
info_ptr = png_create_info_struct(png_ptr);
|
|
||||||
png_set_IHDR(png_ptr, info_ptr,
|
|
||||||
bitmap->width, bitmap->height,
|
|
||||||
depth,
|
|
||||||
PNG_COLOR_TYPE_RGB,
|
|
||||||
PNG_INTERLACE_NONE,
|
|
||||||
PNG_COMPRESSION_TYPE_DEFAULT,
|
|
||||||
PNG_FILTER_TYPE_DEFAULT);
|
|
||||||
|
|
||||||
row_pointers = png_malloc(png_ptr, bitmap->height * sizeof (png_byte *));
|
|
||||||
|
|
||||||
for(y = 0; y < bitmap->height; y++) {
|
|
||||||
png_byte *row = png_malloc(png_ptr, sizeof (uint8_t) * bitmap->width * pixel_size);
|
|
||||||
row_pointers[y] = row;
|
|
||||||
for(x = 0; x < bitmap->width; x++) {
|
|
||||||
pixel_t * pixel = pixel_at(bitmap, x, y);
|
|
||||||
*row++ = pixel->red;
|
|
||||||
*row++ = pixel->green;
|
|
||||||
*row++ = pixel->blue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
png_init_io(png_ptr, fp);
|
|
||||||
png_set_rows(png_ptr, info_ptr, row_pointers);
|
|
||||||
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
|
|
||||||
|
|
||||||
status = 0;
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
SANE_Status status;
|
|
||||||
SANE_Option_Descriptor *desc;
|
|
||||||
SANE_Int vc = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, 1, 10);
|
|
||||||
SANE_Device **device_list;
|
|
||||||
SANE_Handle h;
|
|
||||||
SANE_Parameters p;
|
|
||||||
SANE_Int cap;
|
|
||||||
FILE *file = fopen("lsakjfsalkfd.png", "w");
|
|
||||||
|
|
||||||
status = sane_init(&vc, NULL);
|
|
||||||
sane_get_devices(&device_list, SANE_FALSE);
|
|
||||||
|
|
||||||
for(int i = 0; device_list[i]; i++) {
|
|
||||||
printf("%s %s %s %s\n", device_list[i]->name,
|
|
||||||
device_list[i]->vendor,
|
|
||||||
device_list[i]->model,
|
|
||||||
device_list[i]->type);
|
|
||||||
}
|
|
||||||
if(device_list[0]) sane_open(device_list[0]->name, &h);
|
|
||||||
sane_get_parameters(h, &p);
|
|
||||||
/*
|
|
||||||
printf("%i %i %i\n", p.pixels_per_line, p.lines, p.format);
|
|
||||||
*/
|
|
||||||
const SANE_Byte *storage = malloc(p.bytes_per_line * p.lines);
|
|
||||||
if(!storage) abort();
|
|
||||||
desc = sane_get_option_descriptor(h, (SANE_Int)0);
|
|
||||||
printf("%i\n", desc->cap);
|
|
||||||
int f;
|
|
||||||
sane_control_option(h, 0, SANE_ACTION_GET_VALUE, &f, NULL);
|
|
||||||
cap = f;
|
|
||||||
for(int i = 0; i < cap; i++) {
|
|
||||||
desc = sane_get_option_descriptor(h, (SANE_Int)i);
|
|
||||||
printf("|%i|%s|%s|%s|\n", i, desc->name, desc->title, desc->desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 8; i < 12; i++) {
|
|
||||||
int hello;
|
|
||||||
sane_control_option(h, i, SANE_ACTION_GET_VALUE, &hello, NULL);
|
|
||||||
printf("%i\n", hello);
|
|
||||||
}
|
|
||||||
desc = sane_get_option_descriptor(h, 10);
|
|
||||||
printf("%i\n", desc->unit);
|
|
||||||
SANE_Int info = 0;
|
|
||||||
char valone[100];
|
|
||||||
char valtwo[100];
|
|
||||||
sane_control_option(h, 10, SANE_ACTION_GET_VALUE, &valone, NULL);
|
|
||||||
sane_control_option(h, 11, SANE_ACTION_GET_VALUE, &valtwo, NULL);
|
|
||||||
printf("%s %s\n", valone, valtwo);
|
|
||||||
// sane_control_option(h,
|
|
||||||
|
|
||||||
sane_start(h);
|
|
||||||
SANE_Int len;
|
|
||||||
SANE_Byte *buf = storage;
|
|
||||||
for(;;) {
|
|
||||||
status = sane_read(h, buf, (SANE_Int)80, (SANE_Int *)&len);
|
|
||||||
buf += (int)len;
|
|
||||||
if(status == SANE_STATUS_EOF) break;
|
|
||||||
}
|
|
||||||
bitmap_t *bitmap = malloc(sizeof *bitmap);
|
|
||||||
bitmap->width = p.pixels_per_line;
|
|
||||||
bitmap->height = p.lines;
|
|
||||||
|
|
||||||
bitmap->pixels = (pixel_t *)storage;
|
|
||||||
|
|
||||||
pngtofile(bitmap, file);
|
|
||||||
|
|
||||||
sane_close(h);
|
|
||||||
|
|
||||||
sane_exit();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
from queue import Queue
|
||||||
|
from threading import Thread
|
||||||
|
from threading import Event
|
||||||
|
from time import sleep
|
||||||
|
import sane
|
||||||
|
from PIL import Image
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import select
|
||||||
|
import cv2
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
def is_there_line():
|
||||||
|
# Check if there is any data available to be read from stdin
|
||||||
|
if select.select([sys.stdin], [], [], 0)[0]:
|
||||||
|
# Read the next line from stdin
|
||||||
|
return sys.stdin.readline().rstrip('\n')
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
class Message:
|
||||||
|
def __init__(self, message, payload):
|
||||||
|
self.message = message
|
||||||
|
self.payload = payload
|
||||||
|
|
||||||
|
def interface_thread(i, o):
|
||||||
|
queue = []
|
||||||
|
processing = []
|
||||||
|
scanned = []
|
||||||
|
scanners = []
|
||||||
|
print("<{}>$ ".format(os.getcwd()), end="")
|
||||||
|
sys.stdout.flush()
|
||||||
|
while True:
|
||||||
|
line = is_there_line()
|
||||||
|
if line:
|
||||||
|
# parse the line of input
|
||||||
|
splitted = line.split(' ')
|
||||||
|
if splitted[0] == "queue":
|
||||||
|
if splitted[1] == "add":
|
||||||
|
if splitted[2]:
|
||||||
|
if splitted[2][0] != "/":
|
||||||
|
enqueued = os.path.join(os.getcwd(), splitted[2])
|
||||||
|
else:
|
||||||
|
enqueued = splitted[2]
|
||||||
|
queue.append(enqueued)
|
||||||
|
print("queued file {}".format(enqueued))
|
||||||
|
else:
|
||||||
|
print("specify a file!")
|
||||||
|
elif splitted[0] == "send":
|
||||||
|
print("sending {} to scanner for scanning".format(queue[0]))
|
||||||
|
payload = {
|
||||||
|
'save_location': queue.pop(0),
|
||||||
|
}
|
||||||
|
message = Message("scan_request", payload)
|
||||||
|
o.put(message)
|
||||||
|
elif splitted[0] == "cd":
|
||||||
|
try:
|
||||||
|
os.chdir(splitted[1])
|
||||||
|
except IndexError:
|
||||||
|
os.chdir("/home/usr")
|
||||||
|
elif splitted[0] == "mkdir":
|
||||||
|
os.mkdir(splitted[1])
|
||||||
|
elif splitted[0] == "ls":
|
||||||
|
files = os.listdir()
|
||||||
|
print(files)
|
||||||
|
elif splitted[0] == "feh":
|
||||||
|
subprocess.Popen(["feh", splitted[1]])
|
||||||
|
elif splitted[0] == "scannerlist":
|
||||||
|
o.put(Message("list_scanners", None))
|
||||||
|
data = i.get()
|
||||||
|
if data.message == "list_scanners_resp":
|
||||||
|
scanners = data.payload["scanner_names"]
|
||||||
|
for x in scanners:
|
||||||
|
print(x)
|
||||||
|
i.task_done()
|
||||||
|
elif splitted[0] == "setscanner":
|
||||||
|
payload = {
|
||||||
|
"scanner_name": splitted[1],
|
||||||
|
}
|
||||||
|
message = Message("set_scanner", payload)
|
||||||
|
o.put(message)
|
||||||
|
elif splitted[0] == "sendpredef":
|
||||||
|
o.put(Message("sendpredef", None))
|
||||||
|
elif splitted[0] == "help":
|
||||||
|
print("""help: commands -
|
||||||
|
queue:
|
||||||
|
add: add an item to the queue
|
||||||
|
send: send the first item on the queue to be scanned
|
||||||
|
cd: change directories
|
||||||
|
mkdir: make a directory
|
||||||
|
ls: list files in directory
|
||||||
|
feh: open image viewer
|
||||||
|
scannerlist: list scanners connected
|
||||||
|
setscanner: set the scanner as the selected scanner
|
||||||
|
sendpredef: set the scanner to some predefined settings""")
|
||||||
|
|
||||||
|
print("<{}>$ ".format(os.getcwd()), end="")
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
|
||||||
|
def scanner_backend(i, o):
|
||||||
|
sane.init()
|
||||||
|
scanner = None
|
||||||
|
while True:
|
||||||
|
# Get some data
|
||||||
|
data = i.get()
|
||||||
|
if data.message == "scan_request":
|
||||||
|
save_location = data.payload['save_location']
|
||||||
|
if scanner:
|
||||||
|
print("recieved scan_request with {}".format(save_location))
|
||||||
|
else:
|
||||||
|
print("configure a scanner first")
|
||||||
|
i.task_done()
|
||||||
|
continue
|
||||||
|
|
||||||
|
image = scanner.scan()
|
||||||
|
image.save(data.payload["save_location"])
|
||||||
|
|
||||||
|
i.task_done()
|
||||||
|
elif data.message == "list_scanners":
|
||||||
|
devs = sane.get_devices()
|
||||||
|
payload = {
|
||||||
|
'scanner_names': [x[0] for x in devs],
|
||||||
|
}
|
||||||
|
message = Message("list_scanners_resp", payload)
|
||||||
|
o.put(message)
|
||||||
|
i.task_done()
|
||||||
|
elif data.message == "set_scanner":
|
||||||
|
scanner = sane.open(data.payload["scanner_name"])
|
||||||
|
i.task_done()
|
||||||
|
elif data.message == "sendpredef":
|
||||||
|
# configure the scanner in these predefined ways
|
||||||
|
scanner.resolution = 200
|
||||||
|
scanner.br_x = 320
|
||||||
|
scanner.br_y = 320
|
||||||
|
scanner.calibration_cache = 1
|
||||||
|
i.task_done()
|
||||||
|
|
||||||
|
# Create the shared queue and launch both threads
|
||||||
|
def main():
|
||||||
|
interface_queue, scanner_queue = Queue(), Queue()
|
||||||
|
threads = [
|
||||||
|
Thread(target=interface_thread, args=(interface_queue, scanner_queue)),
|
||||||
|
Thread(target=scanner_backend, args=(scanner_queue, interface_queue)),
|
||||||
|
]
|
||||||
|
[ i.start() for i in threads ]
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in New Issue