1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "palette.h"
#include "debug.h"
#include "types.h"
Palette *
palette_clone(const Palette *p)
{
Palette *res;
/* TODO: better malloc (place list and num together) */
res = malloc(sizeof(Palette));
res->clist = malloc(p->num*sizeof(*p->clist));
res->num = p->num;
memcpy(res->clist, p->clist, p->num * sizeof(*p->clist));
return res;
}
static char *
palette_intern_get_num(char *s, int *a)
{
while (*s == ' ' || *s == '\t')
++s;
if (*s == '\n')
*a = -1;
else {
*a = 0;
while (*s >= '0' && *s <= '9') {
*a = (*a) * 10;
*a += (int) (*s-'0');
++s;
}
}
return s;
}
static uint8
palette_intern_get_color(char *s, Color *c)
{
int a;
char *st = s;
st = palette_intern_get_num(st, &a);
if (a < 0 || a > 255) return 1;
c->r = a;
st = palette_intern_get_num(st, &a);
if (a < 0 || a > 255) return 1;
c->g = a;
st = palette_intern_get_num(st, &a);
if (a < 0 || a > 255) return 1;
c->b = a;
return 0;
}
static uint
palette_intern_get_color_number(const char *s)
{
FILE *fp;
char line[1024];
size_t len = 1024;
uint ans = 0;
fp = fopen(s, "r");
while (fgets(line, len, fp)) {
if (line[0] >= '0' && line[0] <= '9')
++ans;
}
fclose(fp);
return ans;
}
Palette *
palette_open_gpl(const char *p)
{
/* TODO: check if file exists */
/* TODO: better parsing */
/* TODO: better malloc (place list and num together) */
Palette *res;
FILE *fp;
Color *c;
char line[1024];
size_t len = 1024;
res = malloc(sizeof(Palette));
res->num = palette_intern_get_color_number(p);
res->clist = malloc(res->num*sizeof(*res->clist));
c = res->clist;
fp = fopen(p, "r");
while (fgets(line, len, fp)) {
if (line[0] >= '0' && line[0] <= '9') {
if (palette_intern_get_color(line, c)) {
free(res->clist);
free(res);
return NULL;
}
c++;
}
}
fclose(fp);
return res;
}
|