fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 968 lines 17 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/utils/pri/text.c * 7 * Created: 2014-08-18 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2014-2025 Hampa Hug <hampa@hampa.ch> * 9 *****************************************************************************/ 10 11/***************************************************************************** 12 * This program is free software. You can redistribute it and / or modify it * 13 * under the terms of the GNU General Public License version 2 as published * 14 * by the Free Software Foundation. * 15 * * 16 * This program is distributed in the hope that it will be useful, but * 17 * WITHOUT ANY WARRANTY, without even the implied warranty of * 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 19 * Public License for more details. * 20 *****************************************************************************/ 21 22 23#include <config.h> 24 25#include <stdlib.h> 26#include <stdio.h> 27#include <string.h> 28 29#include <drivers/pri/pri.h> 30#include <lib/text.h> 31 32#include "main.h" 33#include "text.h" 34 35 36static int txt_enc_track_finish (pri_text_t *ctx); 37 38 39void txt_save_pos (const pri_text_t *ctx, pri_text_pos_t *pos) 40{ 41 pos->pos = ctx->trk->idx; 42 pos->wrap = ctx->trk->wrap; 43 pos->evt = ctx->trk->cur_evt; 44} 45 46void txt_restore_pos (pri_text_t *ctx, const pri_text_pos_t *pos) 47{ 48 ctx->trk->idx = pos->pos; 49 ctx->trk->wrap = pos->wrap; 50 ctx->trk->cur_evt = pos->evt; 51} 52 53static 54unsigned txt_guess_encoding (pri_trk_t *trk) 55{ 56 unsigned long val, bit; 57 unsigned fm, mfm, gcr; 58 59 pri_trk_set_pos (trk, 0); 60 61 val = 0; 62 63 fm = 0; 64 mfm = 0; 65 gcr = 0; 66 67 while (trk->wrap == 0) { 68 pri_trk_get_bits (trk, &bit, 1); 69 70 val = (val << 1) | (bit & 1); 71 72 switch (val & 0xffffffff) { 73 case 0xaaaaf56f: 74 case 0xaaaaf57e: 75 fm += 1; 76 break; 77 78 case 0x44894489: 79 mfm += 1; 80 break; 81 } 82 83 switch (val & 0xffffff) { 84 case 0xd5aa96: 85 case 0xd5aaad: 86 gcr += 1; 87 break; 88 } 89 } 90 91 fm *= 2; 92 gcr *= 2; 93 94 if ((gcr > 0) && (gcr > fm) && (gcr > mfm)) { 95 return (PRI_TEXT_MAC); 96 } 97 98 if ((fm > 0) && (fm > gcr) && (fm > mfm)) { 99 return (PRI_TEXT_FM); 100 } 101 102 if ((mfm > 0) && (mfm > gcr) && (mfm > fm)) { 103 return (PRI_TEXT_MFM); 104 } 105 106 return (PRI_TEXT_RAW); 107} 108 109int txt_dec_match (pri_text_t *ctx, const void *buf, unsigned cnt) 110{ 111 unsigned i; 112 unsigned long type, val; 113 unsigned long bit; 114 const unsigned char *ptr; 115 pri_text_pos_t pos; 116 117 txt_save_pos (ctx, &pos); 118 119 ptr = buf; 120 121 for (i = 0; i < cnt; i++) { 122 if (pri_trk_get_event (ctx->trk, &type, &val) == 0) { 123 break; 124 } 125 126 pri_trk_get_bits (ctx->trk, &bit, 1); 127 128 if (((ptr[i >> 3] >> (~i & 7)) ^ bit) & 1) { 129 break; 130 } 131 } 132 133 if ((i < cnt) || (ctx->trk->wrap && ctx->trk->idx > 0)) { 134 txt_restore_pos (ctx, &pos); 135 136 return (1); 137 } 138 139 return (0); 140} 141 142void txt_dec_bits (pri_text_t *ctx, unsigned cnt) 143{ 144 unsigned i; 145 unsigned long val; 146 147 val = (ctx->shift >> (ctx->shift_cnt - cnt)) & ((1UL << cnt) - 1); 148 149 ctx->shift_cnt -= cnt; 150 151 if (ctx->column > 0) { 152 fputc ('\n', ctx->txt.fp); 153 } 154 155 fprintf (ctx->txt.fp, "RAW"); 156 157 for (i = 0; i < cnt; i++) { 158 fprintf (ctx->txt.fp, " %lu", (val >> (cnt - i - 1)) & 1); 159 } 160 161 fprintf (ctx->txt.fp, "\n"); 162 163 ctx->column = 0; 164 165 ctx->last_val = val & 1; 166} 167 168void txt_dec_event (pri_text_t *ctx, unsigned long type, unsigned long val) 169{ 170 if (ctx->column > 0) { 171 fputc ('\n', ctx->txt.fp); 172 ctx->column = 0; 173 ctx->need_nl = 0; 174 } 175 176 if (type == PRI_EVENT_WEAK) { 177 fprintf (ctx->txt.fp, "WEAK %08lX\n", val); 178 } 179 else if (type == PRI_EVENT_CLOCK) { 180 unsigned long long tmp; 181 182 tmp = pri_trk_get_clock (ctx->trk); 183 tmp = (tmp * val + 32768) / 65536; 184 185 fprintf (ctx->txt.fp, "CLOCK %lu\n", (unsigned long) tmp); 186 } 187 else { 188 fprintf (ctx->txt.fp, "EVENT %08lX %08lX\n", type, val); 189 } 190} 191 192static 193void txt_dec_init (pri_text_t *ctx, FILE *fp, pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h) 194{ 195 memset (ctx, 0, sizeof (pri_text_t)); 196 197 txt_init (&ctx->txt, fp); 198 199 ctx->img = img; 200 ctx->trk = trk; 201 ctx->c = c; 202 ctx->h = h; 203 ctx->s = 0; 204 205 ctx->mac_align = par_mac_align; 206 ctx->mac_no_slip = par_mac_no_slip; 207} 208 209static 210void txt_dec_free (pri_text_t *ctx) 211{ 212 if (ctx->free_track) { 213 pri_trk_del (ctx->trk); 214 ctx->trk = NULL; 215 } 216 217 txt_free (&ctx->txt); 218} 219 220static 221int pri_decode_text_auto_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 222{ 223 unsigned enc; 224 pri_text_t ctx; 225 226 txt_dec_init (&ctx, opaque, img, trk, c, h); 227 228 enc = txt_guess_encoding (trk); 229 230 if (enc == PRI_TEXT_FM) { 231 txt_fm_dec_track (&ctx); 232 } 233 else if (enc == PRI_TEXT_MFM) { 234 txt_mfm_dec_track (&ctx); 235 } 236 else if (enc == PRI_TEXT_MAC) { 237 txt_mac_dec_track (&ctx); 238 } 239 else { 240 txt_raw_dec_track (&ctx); 241 } 242 243 txt_dec_free (&ctx); 244 245 return (0); 246} 247 248static 249int pri_decode_text_mfm_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 250{ 251 pri_text_t ctx; 252 253 txt_dec_init (&ctx, opaque, img, trk, c, h); 254 txt_mfm_dec_track (&ctx); 255 txt_dec_free (&ctx); 256 257 return (0); 258} 259 260static 261int pri_decode_text_fm_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 262{ 263 pri_text_t ctx; 264 265 txt_dec_init (&ctx, opaque, img, trk, c, h); 266 txt_fm_dec_track (&ctx); 267 txt_dec_free (&ctx); 268 269 return (0); 270} 271 272static 273int pri_decode_text_mac_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 274{ 275 pri_text_t ctx; 276 277 txt_dec_init (&ctx, opaque, img, trk, c, h); 278 txt_mac_dec_track (&ctx); 279 txt_dec_free (&ctx); 280 281 return (0); 282} 283 284static 285int pri_decode_text_raw_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 286{ 287 pri_text_t ctx; 288 289 txt_dec_init (&ctx, opaque, img, trk, c, h); 290 txt_raw_dec_track (&ctx); 291 txt_dec_free (&ctx); 292 293 return (0); 294} 295 296int pri_decode_text (pri_img_t *img, const char *fname, unsigned enc) 297{ 298 int r; 299 FILE *fp; 300 301 if ((fp = fopen (fname, "w")) == NULL) { 302 return (1); 303 } 304 305 fprintf (fp, "PRI 0\n"); 306 307 if (enc == PRI_TEXT_AUTO) { 308 r = pri_for_all_tracks (img, pri_decode_text_auto_cb, fp); 309 } 310 else if (enc == PRI_TEXT_MFM) { 311 r = pri_for_all_tracks (img, pri_decode_text_mfm_cb, fp); 312 } 313 else if (enc == PRI_TEXT_FM) { 314 r = pri_for_all_tracks (img, pri_decode_text_fm_cb, fp); 315 } 316 else if (enc == PRI_TEXT_MAC) { 317 r = pri_for_all_tracks (img, pri_decode_text_mac_cb, fp); 318 } 319 else { 320 r = pri_for_all_tracks (img, pri_decode_text_raw_cb, fp); 321 } 322 323 fclose (fp); 324 325 return (r); 326} 327 328 329unsigned long txt_get_position (pri_text_t *ctx) 330{ 331 unsigned long val; 332 333 val = (ctx->bit_cnt + ctx->offset) & 0xffffffff; 334 335 ctx->offset = 0; 336 337 return (val); 338} 339 340int txt_enc_bits_raw (pri_text_t *ctx, unsigned long val, unsigned cnt) 341{ 342 pri_trk_set_bits (ctx->trk, val, cnt); 343 ctx->bit_cnt += cnt; 344 345 if ((2 * ctx->bit_cnt) > ctx->bit_max) { 346 ctx->bit_max *= 2; 347 348 if (pri_trk_set_size (ctx->trk, ctx->bit_max)) { 349 return (1); 350 } 351 352 pri_trk_set_pos (ctx->trk, ctx->bit_cnt); 353 } 354 355 ctx->last_val = val & 0xff; 356 357 return (0); 358} 359 360static 361int txt_enc_clock (pri_text_t *ctx) 362{ 363 unsigned long pos, val, old; 364 365 if (txt_match_uint (&ctx->txt, 10, &val) == 0) { 366 return (1); 367 } 368 369 if (val > 131072) { 370 old = pri_trk_get_clock (ctx->trk); 371 val = (65536ULL * val + (old / 2)) / old; 372 } 373 374 pos = txt_get_position (ctx); 375 376 if (pri_trk_evt_add (ctx->trk, PRI_EVENT_CLOCK, pos, val) == NULL) { 377 return (1); 378 } 379 380 return (0); 381} 382 383static 384int txt_enc_comm (pri_text_t *ctx) 385{ 386 unsigned cnt; 387 char str[256]; 388 389 if (txt_match (&ctx->txt, "RESET", 1)) { 390 pri_img_set_comment (ctx->img, NULL, 0); 391 return (0); 392 } 393 394 if (txt_match_string (&ctx->txt, str, 256) == 0) { 395 return (1); 396 } 397 398 if (pri_img_add_comment_nl (ctx->img)) { 399 return (1); 400 } 401 402 cnt = strlen (str); 403 404 if (pri_img_add_comment (ctx->img, (unsigned char *) str, cnt)) { 405 return (1); 406 } 407 408 if (pri_img_add_comment (ctx->img, (unsigned char *) "\x0a", 1)) { 409 return (1); 410 } 411 412 return (0); 413} 414 415static 416int txt_enc_index (pri_text_t *ctx) 417{ 418 ctx->index_position = txt_get_position (ctx); 419 420 return (0); 421} 422 423static 424int txt_enc_mode (pri_text_t *ctx) 425{ 426 if (txt_match (&ctx->txt, "RAW", 1)) { 427 ctx->encoding = PRI_TEXT_RAW; 428 } 429 else if (txt_match (&ctx->txt, "IBM-MFM", 1)) { 430 ctx->encoding = PRI_TEXT_MFM; 431 } 432 else if (txt_match (&ctx->txt, "IBM-FM", 1)) { 433 ctx->encoding = PRI_TEXT_FM; 434 } 435 else if (txt_match (&ctx->txt, "MAC-GCR", 1)) { 436 ctx->encoding = PRI_TEXT_MAC; 437 } 438 else if (txt_match (&ctx->txt, "MFM", 1)) { 439 ctx->encoding = PRI_TEXT_MFM; 440 } 441 else if (txt_match (&ctx->txt, "FM", 1)) { 442 ctx->encoding = PRI_TEXT_FM; 443 } 444 else { 445 ctx->encoding = PRI_TEXT_RAW; 446 return (1); 447 } 448 449 return (0); 450} 451 452static 453int txt_enc_offset (pri_text_t *ctx) 454{ 455 unsigned long val; 456 457 if (txt_match_uint (&ctx->txt, 10, &val) == 0) { 458 return (1); 459 } 460 461 ctx->offset = val; 462 463 return (0); 464} 465 466static 467int txt_enc_rate (pri_text_t *ctx) 468{ 469 unsigned long clock; 470 471 if (ctx->trk == NULL) { 472 return (1); 473 } 474 475 if (txt_match_uint (&ctx->txt, 10, &clock) == 0) { 476 return (1); 477 } 478 479 pri_trk_set_clock (ctx->trk, clock); 480 481 return (0); 482} 483 484static 485int txt_enc_raw (pri_text_t *ctx) 486{ 487 unsigned long val; 488 489 while (txt_match_eol (&ctx->txt) == 0) { 490 if (txt_match_uint (&ctx->txt, 16, &val) == 0) { 491 return (1); 492 } 493 494 if ((val != 0) && (val != 1)) { 495 return (1); 496 } 497 498 if (txt_enc_bits_raw (ctx, val, 1)) { 499 return (1); 500 } 501 } 502 503 return (0); 504} 505 506static 507int txt_enc_rotate_track (pri_text_t *ctx) 508{ 509 unsigned long c, h, cnt, max; 510 pri_trk_t *trk; 511 512 if (txt_enc_track_finish (ctx)) { 513 return (1); 514 } 515 516 if (txt_match_uint (&ctx->txt, 10, &c) == 0) { 517 return (1); 518 } 519 520 if (txt_match_uint (&ctx->txt, 10, &h) == 0) { 521 return (1); 522 } 523 524 if (txt_match_uint (&ctx->txt, 10, &cnt) == 0) { 525 return (1); 526 } 527 528 if (cnt == 0) { 529 return (0); 530 } 531 532 if (ctx->img == NULL) { 533 return (1); 534 } 535 536 if ((trk = pri_img_get_track (ctx->img, c, h, 1)) == NULL) { 537 return (1); 538 } 539 540 max = pri_trk_get_size (trk); 541 542 if (max > 0) { 543 if (-cnt < cnt) { 544 cnt = max - (-cnt % max); 545 } 546 547 pri_trk_rotate (trk, cnt); 548 } 549 550 return (0); 551} 552 553static 554int txt_enc_rotate (pri_text_t *ctx) 555{ 556 unsigned long val; 557 558 if (txt_match (&ctx->txt, "TRACK", 1)) { 559 return (txt_enc_rotate_track (ctx)); 560 } 561 562 if (txt_match (&ctx->txt, "SET", 1)) { 563 ctx->rotate = 0; 564 } 565 566 if (txt_match_uint (&ctx->txt, 10, &val) == 0) { 567 return (1); 568 } 569 570 ctx->rotate += val; 571 572 return (0); 573} 574 575static 576int txt_enc_track_finish (pri_text_t *ctx) 577{ 578 if (ctx->trk == NULL) { 579 return (0); 580 } 581 582 if (ctx->bit_cnt == 0) { 583 ctx->trk = NULL; 584 585 pri_img_del_track (ctx->img, ctx->c, ctx->h); 586 587 return (0); 588 } 589 590 if (pri_trk_set_size (ctx->trk, ctx->bit_cnt)) { 591 return (1); 592 } 593 594 if ((ctx->index_position != 0) || (ctx->rotate != 0)) { 595 unsigned long cnt, max, rot; 596 597 max = pri_trk_get_size (ctx->trk); 598 rot = ctx->rotate; 599 600 if (max > 0) { 601 if (-rot < rot) { 602 rot = max - (-rot % max); 603 } 604 605 cnt = (ctx->index_position + rot) % max; 606 pri_trk_rotate (ctx->trk, cnt); 607 } 608 } 609 610 ctx->trk = NULL; 611 612 return (0); 613} 614 615static 616int txt_enc_track_size (pri_text_t *ctx) 617{ 618 unsigned long size; 619 620 if (txt_match_uint (&ctx->txt, 10, &size) == 0) { 621 return (1); 622 } 623 624 ctx->track_size = size; 625 626 return (0); 627} 628 629static 630int txt_enc_track (pri_text_t *ctx) 631{ 632 unsigned long c, h; 633 634 if (txt_match_uint (&ctx->txt, 10, &c) == 0) { 635 return (1); 636 } 637 638 if (txt_match_uint (&ctx->txt, 10, &h) == 0) { 639 return (1); 640 } 641 642 if ((c > 255) || (h > 255)) { 643 txt_error (&ctx->txt, "c/h too large"); 644 return (1); 645 } 646 647 ctx->trk = pri_img_get_track (ctx->img, c, h, 1); 648 649 if (ctx->trk == NULL) { 650 return (1); 651 } 652 653 pri_trk_set_clock (ctx->trk, 500000); 654 pri_trk_evt_del_all (ctx->trk, PRI_EVENT_ALL); 655 656 ctx->c = c; 657 ctx->h = h; 658 659 ctx->bit_cnt = 0; 660 ctx->bit_max = 65536; 661 662 if (pri_trk_set_size (ctx->trk, ctx->bit_max)) { 663 return (1); 664 } 665 666 pri_trk_set_pos (ctx->trk, 0); 667 668 ctx->index_position = 0; 669 ctx->rotate = 0; 670 671 ctx->mac_check_active = 0; 672 ctx->last_val = 0; 673 ctx->crc = 0xffff; 674 675 return (0); 676} 677 678static 679int txt_enc_weak_run (pri_text_t *ctx) 680{ 681 unsigned long pos, cnt, val; 682 683 if (txt_match_uint (&ctx->txt, 10, &cnt) == 0) { 684 return (1); 685 } 686 687 pos = txt_get_position (ctx); 688 val = 0xffffffff; 689 690 while (cnt >= 32) { 691 if (pri_trk_evt_add (ctx->trk, PRI_EVENT_WEAK, pos, val) == NULL) { 692 return (1); 693 } 694 695 pos += 32; 696 cnt -= 32; 697 } 698 699 if (cnt > 0) { 700 val = (val << (32 - cnt)) & 0xffffffff; 701 702 if (pri_trk_evt_add (ctx->trk, PRI_EVENT_WEAK, pos, val) == NULL) { 703 return (1); 704 } 705 } 706 707 return (0); 708} 709 710static 711int txt_enc_weak (pri_text_t *ctx) 712{ 713 int ok; 714 unsigned dig, cnt; 715 unsigned long pos, val; 716 717 if (txt_match (&ctx->txt, "RUN", 1)) { 718 return (txt_enc_weak_run (ctx)); 719 } 720 721 txt_match_space (&ctx->txt); 722 723 pos = txt_get_position (ctx); 724 val = 0; 725 cnt = 0; 726 ok = 0; 727 728 while (txt_match_hex_digit (&ctx->txt, &dig)) { 729 val |= (unsigned long) (dig & 0x0f) << (28 - cnt); 730 cnt += 4; 731 ok = 1; 732 733 if (cnt >= 32) { 734 if (pri_trk_evt_add (ctx->trk, PRI_EVENT_WEAK, pos, val) == NULL) { 735 return (1); 736 } 737 738 pos += 32; 739 val = 0; 740 cnt = 0; 741 } 742 } 743 744 if (cnt > 0) { 745 if (pri_trk_evt_add (ctx->trk, PRI_EVENT_WEAK, pos, val) == NULL) { 746 return (1); 747 } 748 } 749 750 return (ok == 0); 751} 752 753static 754int txt_clean_comment (pri_text_t *ctx) 755{ 756 pri_img_t *img; 757 758 img = ctx->img; 759 760 while (img->comment_size > 0) { 761 if (img->comment[img->comment_size - 1] == 0x0a) { 762 img->comment_size -= 1; 763 } 764 else { 765 break; 766 } 767 } 768 769 return (0); 770} 771 772static 773int txt_encode_pri0 (pri_text_t *ctx) 774{ 775 int r; 776 777 while (1) { 778 switch (ctx->encoding) { 779 case PRI_TEXT_MFM: 780 r = txt_encode_pri0_mfm (ctx); 781 break; 782 783 case PRI_TEXT_FM: 784 r = txt_encode_pri0_fm (ctx); 785 break; 786 787 case PRI_TEXT_MAC: 788 r = txt_encode_pri0_mac (ctx); 789 break; 790 791 case PRI_TEXT_RAW: 792 r = txt_encode_pri0_raw (ctx); 793 break; 794 795 default: 796 r = -1; 797 break; 798 } 799 800 if (r >= 0) { 801 if (r > 0) { 802 return (1); 803 } 804 805 continue; 806 } 807 808 if (txt_match (&ctx->txt, "CLOCK", 1)) { 809 if (txt_enc_clock (ctx)) { 810 txt_error (&ctx->txt, "clock"); 811 return (1); 812 } 813 } 814 else if (txt_match (&ctx->txt, "COMM", 1)) { 815 if (txt_enc_comm (ctx)) { 816 return (1); 817 } 818 } 819 else if (txt_match (&ctx->txt, "INDEX", 1)) { 820 if (txt_enc_index (ctx)) { 821 return (1); 822 } 823 } 824 else if (txt_match (&ctx->txt, "MODE", 1)) { 825 if (txt_enc_mode (ctx)) { 826 return (1); 827 } 828 } 829 else if (txt_match (&ctx->txt, "OFFSET", 1)) { 830 if (txt_enc_offset (ctx)) { 831 return (1); 832 } 833 } 834 else if (txt_match (&ctx->txt, "PRI", 0)) { 835 break; 836 } 837 else if (txt_match (&ctx->txt, "RATE", 1)) { 838 if (txt_enc_rate (ctx)) { 839 return (1); 840 } 841 } 842 else if (txt_match (&ctx->txt, "RAW", 1)) { 843 if (txt_enc_raw (ctx)) { 844 return (1); 845 } 846 } 847 else if (txt_match (&ctx->txt, "ROTATE", 1)) { 848 if (txt_enc_rotate (ctx)) { 849 return (1); 850 } 851 } 852 else if (txt_match (&ctx->txt, "TEXT", 1)) { 853 if (txt_enc_comm (ctx)) { 854 return (1); 855 } 856 } 857 else if (txt_match (&ctx->txt, "TRACK", 1)) { 858 if (txt_match (&ctx->txt, "SIZE", 1)) { 859 if (txt_enc_track_size (ctx)) { 860 return (1); 861 } 862 } 863 else { 864 if (txt_enc_track_finish (ctx)) { 865 return (1); 866 } 867 868 if (txt_enc_track (ctx)) { 869 return (1); 870 } 871 } 872 } 873 else if (txt_match (&ctx->txt, "WEAK", 1) || txt_match (&ctx->txt, "FUZZY", 1)) { 874 if (txt_enc_weak (ctx)) { 875 return (1); 876 } 877 } 878 else if (feof (ctx->txt.fp)) { 879 break; 880 } 881 else { 882 return (1); 883 } 884 } 885 886 if (txt_enc_track_finish (ctx)) { 887 return (1); 888 } 889 890 if (txt_clean_comment (ctx)) { 891 return (1); 892 } 893 894 return (0); 895} 896 897static 898int txt_encode (pri_text_t *ctx) 899{ 900 unsigned long val; 901 902 ctx->trk = NULL; 903 ctx->bit_cnt = 0; 904 ctx->bit_max = 0; 905 ctx->last_val = 0; 906 ctx->encoding = PRI_TEXT_RAW; 907 ctx->index_position = 0; 908 ctx->rotate = 0; 909 ctx->offset = 0; 910 ctx->crc = 0xffff; 911 912 ctx->mac_check_active = 0; 913 ctx->mac_gap_size = 6; 914 915 while (1) { 916 if (txt_match (&ctx->txt, "PRI", 1)) { 917 if (txt_match_uint (&ctx->txt, 10, &val) == 0) { 918 return (1); 919 } 920 921 if (val == 0) { 922 if (txt_encode_pri0 (ctx)) { 923 return (txt_error (&ctx->txt, "PRI")); 924 } 925 } 926 else { 927 return (txt_error (&ctx->txt, "bad pri version")); 928 } 929 } 930 else if (feof (ctx->txt.fp) == 0) { 931 return (txt_error (&ctx->txt, "no pri header")); 932 } 933 else { 934 break; 935 } 936 } 937 938 if (txt_enc_track_finish (ctx)) { 939 return (1); 940 } 941 942 return (0); 943} 944 945int pri_encode_text (pri_img_t *img, const char *fname) 946{ 947 int r; 948 pri_text_t ctx; 949 950 memset (&ctx, 0, sizeof (ctx)); 951 952 ctx.track_size = par_track_size; 953 954 if ((ctx.txt.fp = fopen (fname, "r")) == NULL) { 955 return (1); 956 } 957 958 txt_init (&ctx.txt, ctx.txt.fp); 959 960 ctx.img = img; 961 962 r = txt_encode (&ctx); 963 964 txt_free (&ctx.txt); 965 fclose (ctx.txt.fp); 966 967 return (r); 968}