12 {
13 if(!leny || !lenx){
16 }
17#define MAXCOLORS 65535
18
19 uint32_t* rgba = (uint32_t*)calloc(leny * lenx, sizeof(*rgba));
22 }
23
24 uint32_t* colors = (uint32_t*)calloc(
MAXCOLORS,
sizeof(*colors));
28 }
29
30
31 while(*sx != '#' && *sx != '-'){
32 if(!*sx){
33 logerror(
"expected octothorpe/hyphen, got eol");
35 }
36 ++sx;
37 }
38
39
40 enum {
41 STATE_WANT_HASH,
42 STATE_WANT_COLOR,
43 STATE_WANT_COLORSEMI,
44 STATE_WANT_COLORSPACE,
45 STATE_WANT_DATA,
46 } state = STATE_WANT_HASH;
47 unsigned color = 0;
50 unsigned rle = 1;
51 while(*sx){
52
53 if(*sx == '\e'){
54 break;
55 }
56 if(state == STATE_WANT_HASH){
57 if(*sx == '-'){
60 }else if('#' == *sx){
61 state = STATE_WANT_COLOR;
62 }else{
63 logerror(
"expected octothorpe, got %u", *sx);
64 goto err;
65 }
66 }else if(state == STATE_WANT_COLOR){
67 if(!isdigit(*sx)){
68 logerror(
"expected digit, got %u", *sx);
69 goto err;
70 }
71 color = 0;
72 do{
73
74 color *= 10;
75 color += *sx - '0';
76 ++sx;
77 }while(isdigit(*sx));
78
79 --sx;
80 state = STATE_WANT_COLORSEMI;
81 }else if(state == STATE_WANT_COLORSEMI){
82
83 if(*sx == ';'){
84 state = STATE_WANT_COLORSPACE;
85 }else{
86 state = STATE_WANT_DATA;
87 rle = 1;
88 }
89 }else if(state == STATE_WANT_COLORSPACE){
90 if('2' != *(sx++)){
91 logerror(
"expected '2', got %u", *sx);
92 goto err;
93 }
94
95 if(';' != *(sx++)){
96 logerror(
"expected semicolon, got %u", *sx);
97 goto err;
98 }
99
101 do{
104 ++sx;
105 }while(isdigit(*sx));
106 if(';' != *(sx++)){
107 logerror(
"expected semicolon, got %u", *sx);
108 goto err;
109 }
110
112 int g = 0;
113 do{
114 g *= 10;
115 g += *sx - '0';
116 ++sx;
117 }while(isdigit(*sx));
118 if(';' != *(sx++)){
119 logerror(
"expected semicolon, got %u", *sx);
120 goto err;
121 }
122
123 g = g * 255 / 100;
124 int b = 0;
125 do{
126 b *= 10;
127 b += *sx - '0';
128 ++sx;
129 }while(isdigit(*sx));
130 b = b * 255 / 100;
131 ncpixel_set_a(&colors[color], 0xff);
132 ncpixel_set_rgb8(&colors[color],
r, g, b);
133
135 goto err;
136 }
137 state = STATE_WANT_HASH;
138 --sx;
139 }
140
141 if(state == STATE_WANT_DATA){
142
143 if(*sx == '#'){
144 state = STATE_WANT_HASH;
145 --sx;
146 }else if(*sx == '!'){
147 ++sx;
148 rle = 0;
149 do{
150 rle *= 10;
151 rle += *sx - '0';
152 ++sx;
153 }while(isdigit(*sx));
154 if(0 == rle){
155 rle = 1;
156 }
157 --sx;
158 }else if(*sx == '$'){
160 state = STATE_WANT_DATA;
161 }else if(*sx == '-'){
164 state = STATE_WANT_DATA;
165 }else{
166
167 if(
y + 6 > (leny + 5) / 6 * 6){
168 logerror(
"too many rows %d + 6 > %d",
y, (leny + 5) / 6 * 6);
169 goto err;
170 }
172 logerror(
"invalid rle %d + %d > %d",
x, rle, lenx);
173 goto err;
174 }
175 for(
unsigned xpos =
x ; xpos <
x + rle ; ++xpos){
176 for(
unsigned ypos =
y ; ypos <
y + 6 ; ++ypos){
177 if((*sx - 63) & (1u << (ypos -
y))){
178
179
180 rgba[ypos * lenx + xpos] = colors[color];
181 }
182 }
183 }
185 rle = 1;
186 }
187 }
188 ++sx;
189 }
191 return rgba;
192
193err:
197#undef MAXCOLORS
198}
#define logerror(fmt,...)