Files: b366059646d0ae1ea73ca6a0598323b4db1fd2cf / pngspark.c
2069 bytesRaw
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | static const size_t initial_size = 8; |
11 | |
12 | uint32_t parse_color(const char *color_str) |
13 | { |
14 | if (!color_str) return 0; |
15 | if (color_str[0] == '#') color_str++; |
16 | uint32_t color = strtol(color_str, NULL, 16); |
17 | return 0xff000000 | |
18 | ((color >> 16) | (color & 0x00ff00) | (color & 0xff) << 16); |
19 | } |
20 | |
21 | int pngspark_init(struct pngspark *ps, size_t height, const char *color, |
22 | double scaling) |
23 | { |
24 | ps->size = initial_size; |
25 | ps->num_values = 0; |
26 | ps->values = malloc(initial_size * sizeof(double)); |
27 | if (!ps->values) return 1; |
28 | ps->color = parse_color(color); |
29 | ps->height = height; |
30 | ps->max_value = 0; |
31 | ps->min_value = DBL_MAX; |
32 | ps->scaling = scaling; |
33 | return 0; |
34 | } |
35 | |
36 | int pngspark_append(struct pngspark *ps, double value) |
37 | { |
38 | size_t i = ps->num_values++; |
39 | if (i >= ps->size) { |
40 | ps->values = realloc(ps->values, sizeof(double) * (ps->size <<= 1)); |
41 | if (!ps->values) return 1; |
42 | } |
43 | ps->values[i] = value; |
44 | if (value > ps->max_value) |
45 | ps->max_value = value; |
46 | if (value < ps->min_value) |
47 | ps->min_value = value; |
48 | return 0; |
49 | } |
50 | |
51 | static size_t write_fd(const void *ptr, size_t size, size_t count, |
52 | void *userPtr) |
53 | { |
54 | return fwrite(ptr, size, count, (FILE *)userPtr); |
55 | } |
56 | |
57 | int pngspark_write(struct pngspark *ps, FILE *file) |
58 | { |
59 | size_t height = ps->height; |
60 | size_t width = ps->num_values; |
61 | LuImage *img = luImageCreate(ps->num_values, ps->height, 4, 8); |
62 | if (!img) return 1; |
63 | |
64 | double *values = ps->values; |
65 | uint32_t *pixels = (uint32_t *)img->data; |
66 | ps->min_value *= ps->scaling; |
67 | double height_scale = (double)height / (ps->max_value - ps->min_value); |
68 | |
69 | for (size_t x = 0; x < width; x++) { |
70 | size_t value = height - ((values[x] - ps->min_value) * height_scale); |
71 | for (size_t y = 0; y < value; y++) |
72 | pixels[x + width * y] = 0; |
73 | for (size_t y = value; y < height; y++) |
74 | pixels[x + width * y] = ps->color; |
75 | } |
76 | |
77 | int ret = luPngWrite(write_fd, file, img); |
78 | luImageRelease(img); |
79 | return ret; |
80 | } |
81 | |
82 | void pngspark_end(struct pngspark *ps) |
83 | { |
84 | free(ps->values); |
85 | } |
86 | |
87 |
Built with git-ssb-web