Changeset 918 for libcaca/trunk/cucul/import.c
- Timestamp:
- Apr 26, 2006, 8:59:20 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcaca/trunk/cucul/import.c
r916 r918 76 76 /* Autodetection */ 77 77 if(!strcasecmp("", format)) 78 {79 unsigned int i=0;80 /* if 4 first letters are CACA */81 if(buffer->size >= 4 &&82 buf[0] == 'C' && buf[1] == 'A' && buf[2] == 'C' && buf[3] != 'A')83 return import_caca(buffer->data, buffer->size);84 85 /* If we find ESC[ argv, we guess it's an ANSI file */86 while(i < buffer->size - 1)87 {88 if((buf[i] == 0x1b) && (buf[i+1] == '['))89 return import_ansi(buffer->data, buffer->size);90 i++;91 }92 93 /* Otherwise, import it as text */94 return import_text(buffer->data, buffer->size);95 }78 { 79 unsigned int i=0; 80 /* if 4 first letters are CACA */ 81 if(buffer->size >= 4 && 82 buf[0] == 'C' && buf[1] == 'A' && buf[2] == 'C' && buf[3] != 'A') 83 return import_caca(buffer->data, buffer->size); 84 85 /* If we find ESC[ argv, we guess it's an ANSI file */ 86 while(i < buffer->size - 1) 87 { 88 if((buf[i] == 0x1b) && (buf[i+1] == '[')) 89 return import_ansi(buffer->data, buffer->size); 90 i++; 91 } 92 93 /* Otherwise, import it as text */ 94 return import_text(buffer->data, buffer->size); 95 } 96 96 return NULL; 97 97 } … … 109 109 { 110 110 static char const * const list[] = 111 {112 "", "autodetect",113 "text", "plain text",114 "caca", "native libcaca format",115 "ansi", "ANSI coloured text",116 NULL, NULL117 };111 { 112 "", "autodetect", 113 "text", "plain text", 114 "caca", "native libcaca format", 115 "ansi", "ANSI coloured text", 116 NULL, NULL 117 }; 118 118 119 119 return list; … … 140 140 141 141 width = ((uint32_t)buf[8] << 24) | ((uint32_t)buf[9] << 16) 142 142 | ((uint32_t)buf[10] << 8) | (uint32_t)buf[11]; 143 143 height = ((uint32_t)buf[12] << 24) | ((uint32_t)buf[13] << 16) 144 144 | ((uint32_t)buf[14] << 8) | (uint32_t)buf[15]; 145 145 146 146 if(!width || !height) … … 156 156 157 157 for(n = height * width; n--; ) 158 {159 cv->chars[n] = ((uint32_t)buf[16 + 0 + 8 * n] << 24)160 161 162 163 cv->attr[n] = ((uint32_t)buf[16 + 4 + 8 * n] << 24)164 165 166 167 }158 { 159 cv->chars[n] = ((uint32_t)buf[16 + 0 + 8 * n] << 24) 160 | ((uint32_t)buf[16 + 1 + 8 * n] << 16) 161 | ((uint32_t)buf[16 + 2 + 8 * n] << 8) 162 | (uint32_t)buf[16 + 3 + 8 * n]; 163 cv->attr[n] = ((uint32_t)buf[16 + 4 + 8 * n] << 24) 164 | ((uint32_t)buf[16 + 5 + 8 * n] << 16) 165 | ((uint32_t)buf[16 + 6 + 8 * n] << 8) 166 | (uint32_t)buf[16 + 7 + 8 * n]; 167 } 168 168 169 169 return cv; … … 180 180 181 181 for(i = 0; i < size; i++) 182 {183 unsigned char ch = *text++;184 185 if(ch == '\r')186 continue;187 188 if(ch == '\n')189 {190 x = 0;191 y++;192 continue;193 }194 195 if(x >= width || y >= height)196 {197 if(x >= width)198 width = x + 1;199 200 if(y >= height)201 height = y + 1;202 203 cucul_set_canvas_size(cv, width, height);204 }205 206 cucul_putchar(cv, x, y, ch);207 x++;208 }182 { 183 unsigned char ch = *text++; 184 185 if(ch == '\r') 186 continue; 187 188 if(ch == '\n') 189 { 190 x = 0; 191 y++; 192 continue; 193 } 194 195 if(x >= width || y >= height) 196 { 197 if(x >= width) 198 width = x + 1; 199 200 if(y >= height) 201 height = y + 1; 202 203 cucul_set_canvas_size(cv, width, height); 204 } 205 206 cucul_putchar(cv, x, y, ch); 207 x++; 208 } 209 209 210 210 return cv; … … 224 224 225 225 for(i = 0; i < size; i += skip) 226 { 227 skip = 1; 228 229 /* Wrap long lines */ 230 if((unsigned int)x >= width) 231 { 232 x = 0; 233 y++; 234 } 235 236 if(buffer[i] == '\x1a' && size - i >= 8 237 && !memcmp(buffer + i + 1, "SAUCE00", 7)) 238 break; /* End before SAUCE data */ 239 240 if(buffer[i] == '\r') 241 continue; /* DOS sucks */ 242 243 if(buffer[i] == '\n') 244 { 245 x = 0; 246 y++; 247 continue; 248 } 249 250 /* Interpret escape commands, as per Standard ECMA-48 "Control 251 * Functions for Coded Character Sets", 5.4. Control sequences. */ 252 if(buffer[i] == '\x1b' && buffer[i + 1] == '[') 253 { 254 unsigned int argc = 0, argv[101]; 255 unsigned int param, inter, final; 256 257 /* Compute offsets to parameter bytes, intermediate bytes and 258 * to the final byte. Only the final byte is mandatory, there 259 * can be zero of the others. 260 * 0 param=2 inter final final+1 261 * +-----+------------------+---------------------+-----------------+ 262 * | CSI | parameter bytes | intermediate bytes | final byte | 263 * | | 0x30 - 0x3f | 0x20 - 0x2f | 0x40 - 0x7e | 264 * | ^[[ | 0123456789:;<=>? | SPC !"#$%&'()*+,-./ | azAZ@[\]^_`{|}~ | 265 * +-----+------------------+---------------------+-----------------+ 266 */ 267 param = 2; 268 269 for(inter = param; i + inter < size; inter++) 270 if(buffer[i + inter] < 0x30 || buffer[i + inter] > 0x3f) 271 break; 272 273 for(final = inter; i + final < size; final++) 274 if(buffer[i + final] < 0x20 || buffer[i + final] > 0x2f) 275 break; 276 277 if(buffer[i + final] < 0x40 || buffer[i + final] > 0x7e) 278 break; /* Invalid Final Byte */ 279 280 skip += final; 281 282 /* Sanity checks */ 283 if(param < inter && buffer[i + param] >= 0x3c) 284 { 285 fprintf(stderr, "private sequence \"^[[%.*s\"\n", 286 final - param + 1, buffer + i + param); 287 continue; /* Private sequence, skip it entirely */ 288 } 289 290 if(final - param > 100) 291 continue; /* Suspiciously long sequence, skip it */ 292 293 /* Parse parameter bytes as per ECMA-48 5.4.2: Parameter string 294 * format */ 295 if(param < inter) 296 { 297 argv[0] = 0; 298 for(j = param; j < inter; j++) 299 { 300 if(buffer[i + j] == ';') 301 argv[++argc] = 0; 302 else if(buffer[i + j] >= '0' && buffer[i + j] <= '9') 303 argv[argc] = 10 * argv[argc] + (buffer[i + j] - '0'); 304 } 305 argc++; 306 } 307 308 /* Interpret final byte. The code representations are given in 309 * ECMA-48 5.4: Control sequences, and the code definitions are 310 * given in ECMA-48 8.3: Definition of control functions. */ 311 switch(buffer[i + final]) 312 { 313 case 'f': /* CUP - Cursor Position */ 314 case 'H': /* HVP - Character And Line Position */ 315 x = (argc > 1) ? argv[1] - 1 : 0; 316 y = (argc > 0) ? argv[0] - 1 : 0; 317 break; 318 case 'A': /* CUU - Cursor Up */ 319 y -= argc ? argv[0] : 1; 320 if(y < 0) 321 y = 0; 322 break; 323 case 'B': /* CUD - Cursor Down */ 324 y += argc ? argv[0] : 1; 325 break; 326 case 'C': /* CUF - Cursor Right */ 327 x += argc ? argv[0] : 1; 328 break; 329 case 'D': /* CUB - Cursor Left */ 330 x -= argc ? argv[0] : 1; 331 if(x < 0) 226 { 227 skip = 1; 228 229 /* Wrap long lines */ 230 if((unsigned int)x >= width) 231 { 332 232 x = 0; 333 break; 334 case 's': /* Private (save cursor position) */ 335 save_x = x; 336 save_y = y; 337 break; 338 case 'u': /* Private (reload cursor positin) */ 339 x = save_x; 340 y = save_y; 341 break; 342 case 'J': /* ED - Erase In Page */ 343 if(argv[0] == 2) 344 x = y = 0; 345 break; 346 case 'K': /* EL - Erase In Line */ 347 for(j = x; j < width; j++) 348 _cucul_putchar32(cv, j, y, (uint32_t)' '); 349 x = width; 350 break; 351 case 'm': /* SGR - Select Graphic Rendition */ 352 ansi_parse_grcm(cv, &grcm, argc, argv); 353 break; 354 default: 355 fprintf(stderr, "unknown command %c\n", buffer[i + final]); 356 break; 357 } 358 359 continue; 360 } 361 362 /* We're going to paste a character. First make sure the canvas 363 * is big enough. */ 364 if((unsigned int)y >= height) 365 { 366 height = y + 1; 367 cucul_set_canvas_size(cv, width, height); 368 } 369 370 /* Now paste our character */ 371 _cucul_putchar32(cv, x, y, _cucul_cp437_to_utf32(buffer[i])); 372 x++; 373 } 233 y++; 234 } 235 236 if(buffer[i] == '\x1a' && size - i >= 8 237 && !memcmp(buffer + i + 1, "SAUCE00", 7)) 238 break; /* End before SAUCE data */ 239 240 if(buffer[i] == '\r') 241 continue; /* DOS sucks */ 242 243 if(buffer[i] == '\n') 244 { 245 x = 0; 246 y++; 247 continue; 248 } 249 250 /* Interpret escape commands, as per Standard ECMA-48 "Control 251 * Functions for Coded Character Sets", 5.4. Control sequences. */ 252 if(buffer[i] == '\x1b' && buffer[i + 1] == '[') 253 { 254 unsigned int argc = 0, argv[101]; 255 unsigned int param, inter, final; 256 257 /* Compute offsets to parameter bytes, intermediate bytes and 258 * to the final byte. Only the final byte is mandatory, there 259 * can be zero of the others. 260 * 0 param=2 inter final final+1 261 * +-----+------------------+---------------------+-----------------+ 262 * | CSI | parameter bytes | intermediate bytes | final byte | 263 * | | 0x30 - 0x3f | 0x20 - 0x2f | 0x40 - 0x7e | 264 * | ^[[ | 0123456789:;<=>? | SPC !"#$%&'()*+,-./ | azAZ@[\]^_`{|}~ | 265 * +-----+------------------+---------------------+-----------------+ 266 */ 267 param = 2; 268 269 for(inter = param; i + inter < size; inter++) 270 if(buffer[i + inter] < 0x30 || buffer[i + inter] > 0x3f) 271 break; 272 273 for(final = inter; i + final < size; final++) 274 if(buffer[i + final] < 0x20 || buffer[i + final] > 0x2f) 275 break; 276 277 if(buffer[i + final] < 0x40 || buffer[i + final] > 0x7e) 278 break; /* Invalid Final Byte */ 279 280 skip += final; 281 282 /* Sanity checks */ 283 if(param < inter && buffer[i + param] >= 0x3c) 284 { 285 fprintf(stderr, "private sequence \"^[[%.*s\"\n", 286 final - param + 1, buffer + i + param); 287 continue; /* Private sequence, skip it entirely */ 288 } 289 290 if(final - param > 100) 291 continue; /* Suspiciously long sequence, skip it */ 292 293 /* Parse parameter bytes as per ECMA-48 5.4.2: Parameter string 294 * format */ 295 if(param < inter) 296 { 297 argv[0] = 0; 298 for(j = param; j < inter; j++) 299 { 300 if(buffer[i + j] == ';') 301 argv[++argc] = 0; 302 else if(buffer[i + j] >= '0' && buffer[i + j] <= '9') 303 argv[argc] = 10 * argv[argc] + (buffer[i + j] - '0'); 304 } 305 argc++; 306 } 307 308 /* Interpret final byte. The code representations are given in 309 * ECMA-48 5.4: Control sequences, and the code definitions are 310 * given in ECMA-48 8.3: Definition of control functions. */ 311 switch(buffer[i + final]) 312 { 313 case 'f': /* CUP - Cursor Position */ 314 case 'H': /* HVP - Character And Line Position */ 315 x = (argc > 1) ? argv[1] - 1 : 0; 316 y = (argc > 0) ? argv[0] - 1 : 0; 317 break; 318 case 'A': /* CUU - Cursor Up */ 319 y -= argc ? argv[0] : 1; 320 if(y < 0) 321 y = 0; 322 break; 323 case 'B': /* CUD - Cursor Down */ 324 y += argc ? argv[0] : 1; 325 break; 326 case 'C': /* CUF - Cursor Right */ 327 x += argc ? argv[0] : 1; 328 break; 329 case 'D': /* CUB - Cursor Left */ 330 x -= argc ? argv[0] : 1; 331 if(x < 0) 332 x = 0; 333 break; 334 case 's': /* Private (save cursor position) */ 335 save_x = x; 336 save_y = y; 337 break; 338 case 'u': /* Private (reload cursor positin) */ 339 x = save_x; 340 y = save_y; 341 break; 342 case 'J': /* ED - Erase In Page */ 343 if(argv[0] == 2) 344 x = y = 0; 345 break; 346 case 'K': /* EL - Erase In Line */ 347 for(j = x; j < width; j++) 348 _cucul_putchar32(cv, j, y, (uint32_t)' '); 349 x = width; 350 break; 351 case 'm': /* SGR - Select Graphic Rendition */ 352 ansi_parse_grcm(cv, &grcm, argc, argv); 353 break; 354 default: 355 fprintf(stderr, "unknown command %c\n", buffer[i + final]); 356 break; 357 } 358 359 continue; 360 } 361 362 /* We're going to paste a character. First make sure the canvas 363 * is big enough. */ 364 if((unsigned int)y >= height) 365 { 366 height = y + 1; 367 cucul_set_canvas_size(cv, width, height); 368 } 369 370 /* Now paste our character */ 371 _cucul_putchar32(cv, x, y, _cucul_cp437_to_utf32(buffer[i])); 372 x++; 373 } 374 374 375 375 return cv; … … 382 382 { 383 383 static uint8_t const ansi2cucul[] = 384 {385 CUCUL_COLOR_BLACK, CUCUL_COLOR_RED,386 CUCUL_COLOR_GREEN, CUCUL_COLOR_BROWN,387 CUCUL_COLOR_BLUE, CUCUL_COLOR_MAGENTA,388 CUCUL_COLOR_CYAN, CUCUL_COLOR_LIGHTGRAY389 };384 { 385 CUCUL_COLOR_BLACK, CUCUL_COLOR_RED, 386 CUCUL_COLOR_GREEN, CUCUL_COLOR_BROWN, 387 CUCUL_COLOR_BLUE, CUCUL_COLOR_MAGENTA, 388 CUCUL_COLOR_CYAN, CUCUL_COLOR_LIGHTGRAY 389 }; 390 390 391 391 unsigned int j; … … 393 393 394 394 for(j = 0; j < argc; j++) 395 {396 /* Defined in ECMA-48 8.3.117: SGR - SELECT GRAPHIC RENDITION */397 if(argv[j] >= 30 && argv[j] <= 37)398 g->fg = ansi2cucul[argv[j] - 30];399 else if(argv[j] >= 40 && argv[j] <= 47)400 g->bg = ansi2cucul[argv[j] - 40];401 else if(argv[j] >= 90 && argv[j] <= 97)402 g->fg = ansi2cucul[argv[j] - 90] + 8;403 else if(argv[j] >= 100 && argv[j] <= 107)404 g->bg = ansi2cucul[argv[j] - 100] + 8;405 else switch(argv[j])406 {407 case 0: /* default rendition */408 g->fg = CUCUL_COLOR_DEFAULT;409 g->bg = CUCUL_COLOR_DEFAULT;410 g->bold = g->negative = g->concealed = 0;411 break;412 case 1: /* bold or increased intensity */413 g->bold = 1;414 break;415 case 4: /* singly underlined */416 break;417 case 5: /* slowly blinking (less then 150 per minute) */418 break;419 case 7: /* negative image */420 g->negative = 1;421 break;422 case 8: /* concealed characters */423 g->concealed = 1;424 break;425 case 22: /* normal colour or normal intensity (neither bold nor faint) */426 g->bold = 0;427 break;428 case 28: /* revealed characters */429 g->concealed = 0;430 break;431 case 39: /* default display colour (implementation-defined) */432 g->fg = CUCUL_COLOR_DEFAULT;433 break;434 case 49: /* default background colour (implementation-defined) */435 g->bg = CUCUL_COLOR_DEFAULT;436 break;437 default:438 fprintf(stderr, "unknown sgr %i\n", argv[j]);439 break;440 }441 }395 { 396 /* Defined in ECMA-48 8.3.117: SGR - SELECT GRAPHIC RENDITION */ 397 if(argv[j] >= 30 && argv[j] <= 37) 398 g->fg = ansi2cucul[argv[j] - 30]; 399 else if(argv[j] >= 40 && argv[j] <= 47) 400 g->bg = ansi2cucul[argv[j] - 40]; 401 else if(argv[j] >= 90 && argv[j] <= 97) 402 g->fg = ansi2cucul[argv[j] - 90] + 8; 403 else if(argv[j] >= 100 && argv[j] <= 107) 404 g->bg = ansi2cucul[argv[j] - 100] + 8; 405 else switch(argv[j]) 406 { 407 case 0: /* default rendition */ 408 g->fg = CUCUL_COLOR_DEFAULT; 409 g->bg = CUCUL_COLOR_DEFAULT; 410 g->bold = g->negative = g->concealed = 0; 411 break; 412 case 1: /* bold or increased intensity */ 413 g->bold = 1; 414 break; 415 case 4: /* singly underlined */ 416 break; 417 case 5: /* slowly blinking (less then 150 per minute) */ 418 break; 419 case 7: /* negative image */ 420 g->negative = 1; 421 break; 422 case 8: /* concealed characters */ 423 g->concealed = 1; 424 break; 425 case 22: /* normal colour or normal intensity (neither bold nor faint) */ 426 g->bold = 0; 427 break; 428 case 28: /* revealed characters */ 429 g->concealed = 0; 430 break; 431 case 39: /* default display colour (implementation-defined) */ 432 g->fg = CUCUL_COLOR_DEFAULT; 433 break; 434 case 49: /* default background colour (implementation-defined) */ 435 g->bg = CUCUL_COLOR_DEFAULT; 436 break; 437 default: 438 fprintf(stderr, "unknown sgr %i\n", argv[j]); 439 break; 440 } 441 } 442 442 443 443 if(g->concealed) 444 {445 myfg = mybg = CUCUL_COLOR_TRANSPARENT;446 }444 { 445 myfg = mybg = CUCUL_COLOR_TRANSPARENT; 446 } 447 447 else 448 {449 myfg = g->negative ? g->bg : g->fg;450 mybg = g->negative ? g->fg : g->bg;451 452 if(g->bold)453 {454 if(myfg < 8)455 myfg += 8;456 else if(myfg == CUCUL_COLOR_DEFAULT)457 myfg = CUCUL_COLOR_WHITE;458 }459 }448 { 449 myfg = g->negative ? g->bg : g->fg; 450 mybg = g->negative ? g->fg : g->bg; 451 452 if(g->bold) 453 { 454 if(myfg < 8) 455 myfg += 8; 456 else if(myfg == CUCUL_COLOR_DEFAULT) 457 myfg = CUCUL_COLOR_WHITE; 458 } 459 } 460 460 461 461 cucul_set_color(cv, myfg, mybg);
Note: See TracChangeset
for help on using the changeset viewer.