Date: | 2011-04-28 05:38:13 (12 years 11 months ago) |
---|---|
Author: | Werner Almesberger |
Commit: | 080978ade0464da28a0119f0ce0c71e4a1e47bd1 |
Message: | ubb-vga2: added support for showing a PPM image - Makefile (OBJS): added ppm.o and ppmimg.o - ppm.h (load_ppm), ppm.c: PPM file loader, adapted from eda-tools/schhist/ppmdiff/ppmdiff.c - ubb-vga.h (img_name, ppmimg), ppmimg.c: PPM image to frame buffer converter - ubb-vga2.c (usage, main): the threshold is now set with the option -l - ubb-vga2.c (usage, main): if a second argument is given, treat it as a PPM file - ubb-vga2.c (usage): also documented option -t |
Files: |
ubb-vga/Makefile (1 diff) ubb-vga/ppm.c (1 diff) ubb-vga/ppm.h (1 diff) ubb-vga/ppmimg.c (1 diff) ubb-vga/ubb-vga.h (1 diff) ubb-vga/ubb-vga2.c (3 diffs) |
Change Details
ubb-vga/Makefile | ||
---|---|---|
3 | 3 | |
4 | 4 | CFLAGS=-Wall -g -O9 -march=mips32 |
5 | 5 | LDFLAGS=-lm |
6 | OBJS=ubb-vga2.o grabfb.o tstimg.o | |
6 | OBJS=ubb-vga2.o grabfb.o tstimg.o ppm.o ppmimg.o | |
7 | 7 | |
8 | 8 | .PHONY: all asm sch clean spotless |
9 | 9 |
ubb-vga/ppm.c | ||
---|---|---|
1 | /* | |
2 | * ppm.c - Load a PPM image | |
3 | * | |
4 | * Written 2010-2011 by Werner Almesberger | |
5 | * Copyright 2010-2011 Werner Almesberger | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | */ | |
12 | ||
13 | ||
14 | #include <stdint.h> | |
15 | #include <stdlib.h> | |
16 | #include <stdio.h> | |
17 | #include <string.h> | |
18 | ||
19 | #include "ppm.h" | |
20 | ||
21 | ||
22 | static char *fgets_comment(char *line, int n, FILE *file) | |
23 | { | |
24 | do { | |
25 | if (!fgets(line, n, file)) | |
26 | return NULL; | |
27 | } | |
28 | while (*line == '#'); | |
29 | return line; | |
30 | } | |
31 | ||
32 | ||
33 | uint8_t *load_ppm(const char *name, int *x, int *y) | |
34 | { | |
35 | FILE *file; | |
36 | char line[100]; | |
37 | int this_x, this_y, depth; | |
38 | int n; | |
39 | uint8_t *img; | |
40 | ||
41 | file = fopen(name, "r"); | |
42 | if (!file) { | |
43 | perror(name); | |
44 | exit(1); | |
45 | } | |
46 | if (!fgets_comment(line, sizeof(line), file)) { | |
47 | fprintf(stderr, "can't read file type\n"); | |
48 | exit(1); | |
49 | } | |
50 | if (strcmp(line, "P6\n")) { | |
51 | fprintf(stderr, "file type must be P6, not %s", line); | |
52 | exit(1); | |
53 | } | |
54 | if (!fgets_comment(line, sizeof(line), file)) { | |
55 | fprintf(stderr, "can't read resolution\n"); | |
56 | exit(1); | |
57 | } | |
58 | if (sscanf(line, "%d %d", &this_x, &this_y) != 2) { | |
59 | fprintf(stderr, "can't parse resolution: %s", line); | |
60 | exit(1); | |
61 | } | |
62 | if (*x || *y) { | |
63 | if (*x != this_x || *y != this_y) { | |
64 | fprintf(stderr, | |
65 | "resolution changed from %dx%d to %dx%d\n", | |
66 | *x, *y, this_x, this_y); | |
67 | exit(1); | |
68 | } | |
69 | } else { | |
70 | *x = this_x; | |
71 | *y = this_y; | |
72 | } | |
73 | if (!fgets_comment(line, sizeof(line), file)) { | |
74 | fprintf(stderr, "can't read depth\n"); | |
75 | exit(1); | |
76 | } | |
77 | if (sscanf(line, "%d", &depth) != 1) { | |
78 | fprintf(stderr, "can't parse depth: %s", line); | |
79 | exit(1); | |
80 | } | |
81 | if (depth != 255) { | |
82 | fprintf(stderr, "depth must be 255, not %d\n", depth); | |
83 | exit(1); | |
84 | } | |
85 | n = *x**y*3; | |
86 | img = malloc(n); | |
87 | if (!img) { | |
88 | perror("malloc"); | |
89 | exit(1); | |
90 | } | |
91 | if (fread(img, 1, n, file) != n) { | |
92 | fprintf(stderr, "can't read %d bytes\n", n); | |
93 | exit(1); | |
94 | } | |
95 | fclose(file); | |
96 | return img; | |
97 | } |
ubb-vga/ppm.h | ||
---|---|---|
1 | /* | |
2 | * ppm.h - Load a PPM image | |
3 | * | |
4 | * Written 2011 by Werner Almesberger | |
5 | * Copyright 2011 Werner Almesberger | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | */ | |
12 | ||
13 | ||
14 | #ifndef PPM_H | |
15 | #define PPM_H | |
16 | ||
17 | #include <stdint.h> | |
18 | ||
19 | ||
20 | uint8_t *load_ppm(const char *name, int *x, int *y); | |
21 | ||
22 | #endif /* !PPM_H */ | |
23 |
ubb-vga/ppmimg.c | ||
---|---|---|
1 | /* | |
2 | * ppmimg.c - Convert a PPM image | |
3 | * | |
4 | * Written 2011 by Werner Almesberger | |
5 | * Copyright 2011 Werner Almesberger | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | */ | |
12 | ||
13 | ||
14 | #include <stdint.h> | |
15 | #include <stdlib.h> | |
16 | #include <stdio.h> | |
17 | ||
18 | #include "ppm.h" | |
19 | #include "ubb-vga.h" | |
20 | ||
21 | ||
22 | char *img_name; | |
23 | ||
24 | ||
25 | static uint8_t pattern(int r, int g, int b) | |
26 | { | |
27 | return ((r ? R_VAL : 0) | (g ? G_VAL : 0) | (b ? B_VAL : 0))*0x11; | |
28 | } | |
29 | ||
30 | ||
31 | static void convert(uint8_t *f, int xres, int yres, uint8_t *ppm) | |
32 | { | |
33 | int x, y; | |
34 | uint8_t v, last = 0; | |
35 | ||
36 | for (y = 0; y != yres; y++) | |
37 | for (x = 0; x != xres; x++) { | |
38 | v = pattern(ppm[0] >= thres, ppm[1] >= thres, | |
39 | ppm[2] >= thres); | |
40 | if (x & 1) { | |
41 | *f++ = last | v; | |
42 | } else { | |
43 | last = v << 4; | |
44 | } | |
45 | ppm += 3; | |
46 | } | |
47 | } | |
48 | ||
49 | ||
50 | void ppmimg(void *f, int xres, int yres) | |
51 | { | |
52 | uint8_t *ppm; | |
53 | int xr = 0, yr = 0; | |
54 | ||
55 | ppm = load_ppm(img_name, &xr, &yr); | |
56 | if (xr != xres || yr != yres) { | |
57 | fprintf(stderr, "image is %dx%d, display is %dx%d\n", | |
58 | xr, yr, xres, yres); | |
59 | exit(1); | |
60 | } | |
61 | convert(f, xres, yres, ppm); | |
62 | free(ppm); | |
63 | } |
ubb-vga/ubb-vga.h | ||
---|---|---|
26 | 26 | void *map(off_t addr, size_t size); |
27 | 27 | |
28 | 28 | |
29 | /* grabfb.c */ | |
30 | ||
29 | 31 | extern uint8_t thres; |
30 | 32 | |
31 | 33 | void grabfb(void *f, int xres, int yres); |
32 | 34 | |
35 | /* tstimg.c */ | |
36 | ||
33 | 37 | void tstimg(void *f, int xres, int yres); |
34 | 38 | |
39 | /* ppmimg.c */ | |
40 | ||
41 | extern char *img_name; | |
42 | ||
43 | void ppmimg(void *f, int xres, int yres); | |
44 | ||
35 | 45 | #endif /* !UBB_VGA_H */ |
ubb-vga/ubb-vga2.c | ||
---|---|---|
410 | 410 | static void usage(const char *name) |
411 | 411 | { |
412 | 412 | fprintf(stderr, |
413 | "usage: %s frames [threshold]\n\n" | |
414 | " frames number of frames to display\n" | |
415 | " threshold channel on/off threshold\n\n" | |
413 | "usage: %s [-l threshold] [-t] frames [file]\n\n" | |
414 | " frames number of frames to display\n" | |
415 | " file PPM file\n\n" | |
416 | " -l threshold channel on/off threshold\n" | |
417 | " -t generate a test image\n" | |
416 | 418 | , name); |
417 | 419 | exit(1); |
418 | 420 | } |
... | ... | |
424 | 426 | int frames; |
425 | 427 | int c; |
426 | 428 | |
427 | while ((c = getopt(argc, argv, "t")) != EOF) | |
429 | while ((c = getopt(argc, argv, "l:t")) != EOF) | |
428 | 430 | switch (c) { |
431 | case 'l': | |
432 | thres = atoi(optarg); | |
433 | break; | |
429 | 434 | case 't': |
430 | 435 | gen = tstimg; |
431 | 436 | break; |
... | ... | |
435 | 440 | |
436 | 441 | switch (argc-optind) { |
437 | 442 | case 2: |
438 | thres = atoi(argv[optind+1]); | |
443 | img_name = argv[optind+1]; | |
444 | gen = ppmimg; | |
439 | 445 | /* fall through */ |
440 | 446 | case 1: |
441 | 447 | frames = atoi(argv[optind]); |
Branches:
master