fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
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}