home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / APPS / macutils.lzh / MACUTILS / HEXBIN / hqx.c < prev    next >
C/C++ Source or Header  |  1996-02-01  |  9KB  |  397 lines

  1. #include "hexbin.h"
  2. #ifdef HQX
  3. #include "globals.h"
  4. #include "readline.h"
  5. #include "crc.h"
  6. #include "buffer.h"
  7. #include "../fileio/machdr.h"
  8. #include "../fileio/wrfile.h"
  9. #include "../util/util.h"
  10. #include "printhdr.h"
  11.  
  12. extern void exit();
  13.  
  14. static void get_header();
  15. static void oflush();
  16. static int getq();
  17. static long get2q();
  18. static long get4q();
  19. static getqbuf();
  20.  
  21. static char *g_macname;
  22.  
  23. /* New stuff which hopes to improve the speed. */
  24.  
  25. #define RUNCHAR 0x90
  26.  
  27. #define DONE 0x7F
  28. #define SKIP 0x7E
  29. #define FAIL 0x7D
  30.  
  31. static char lookup[256] = {
  32. /*       ^@    ^A    ^B    ^C    ^D    ^E    ^F    ^G   */
  33. /* 0*/    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  34. /*       \b    \t    \n    ^K    ^L    \r    ^N    ^O   */
  35. /* 1*/    FAIL, FAIL, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL,
  36. /*       ^P    ^Q    ^R    ^S    ^T    ^U    ^V    ^W   */
  37. /* 2*/    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  38. /*       ^X    ^Y    ^Z    ^[    ^\    ^]    ^^    ^_   */
  39. /* 3*/    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  40. /*              !     "     #     $     %     &     '   */
  41. /* 4*/    FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
  42. /*        (     )     *     +     ,     -     .     /   */
  43. /* 5*/    0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, FAIL, FAIL,
  44. /*        0     1     2     3     4     5     6     7   */
  45. /* 6*/    0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, FAIL,
  46. /*        8     9     :     ;     <     =     >     ?   */
  47. /* 7*/    0x14, 0x15, DONE, FAIL, FAIL, FAIL, FAIL, FAIL,
  48. /*        @     A     B     C     D     E     F     G   */
  49. /* 8*/    0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
  50. /*        H     I     J     K     L     M     N     O   */
  51. /* 9*/    0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, FAIL,
  52. /*        P     Q     R     S     T     U     V     W   */
  53. /*10*/    0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, FAIL,
  54. /*        X     Y     Z     [     \     ]     ^     _   */
  55. /*11*/    0x2C, 0x2D, 0x2E, 0x2F, FAIL, FAIL, FAIL, FAIL,
  56. /*        `     a     b     c     d     e     f     g   */
  57. /*12*/    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, FAIL,
  58. /*        h     i     j     k     l     m     n     o   */
  59. /*13*/    0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, FAIL, FAIL,
  60. /*        p     q     r     s     t     u     v     w   */
  61. /*14*/    0x3D, 0x3E, 0x3F, FAIL, FAIL, FAIL, FAIL, FAIL,
  62. /*        x     y     z     {     |     }     ~    ^?   */
  63. /*15*/    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  64. /*16*/    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  65.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  66.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  67.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  68.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  69.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  70.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  71.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  72.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  73.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  74.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  75.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  76.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  77.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  78.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  79.     FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
  80. };
  81.  
  82. static int stop = 0;
  83.  
  84. static unsigned char obuf[BUFSIZ];
  85. static unsigned char *op = obuf;
  86. static unsigned char *oq;
  87.  
  88. #define S_HEADER      0
  89. #define S_DATAOPEN    1
  90. #define S_DATAWRITE   2
  91. #define S_DATAC1      3
  92. #define S_DATAC2      4
  93. #define S_RSRCOPEN    5
  94. #define S_RSRCWRITE   6
  95. #define S_RSRCC1      7
  96. #define S_RSRCC2      8
  97. #define S_EXCESS      9
  98.  
  99. static int ostate = S_HEADER;
  100.  
  101. static unsigned long calc_crc;
  102. static unsigned long file_crc;
  103.  
  104. static long todo;
  105.  
  106. #define output(c) { *op++ = (c); if(op >= &obuf[BUFSIZ]) oflush(); }
  107.  
  108. void hqx(macname)
  109. char *macname;
  110. {
  111.     int n, normlen, c;
  112.     register char *in, *out;
  113.     register int b6, b8, data, lastc = 0;
  114.     char state68 = 0, run = 0, linestate, first = 1;
  115.  
  116.     g_macname = macname;
  117.  
  118.     ostate = S_HEADER;
  119.     stop = 0;
  120.  
  121.     while(!stop) {
  122.     n = strlen((char *)line);
  123.     while(n > 0 && line[n - 1] == ' ') {
  124.         n--;
  125.     }
  126.     out = line+n;
  127.     if(uneven_lines) {
  128.          goto skipcheck;
  129.     }
  130.     if(first) {
  131.         normlen = n;
  132.     }
  133.     /* Check line for intermediate garbage */
  134.     linestate = SKIP;
  135.     for(in = line; in < out; in++) {
  136.         if((linestate = lookup[*in & 0xff]) == FAIL ||
  137.         ((linestate == DONE) && !first)) {
  138.         break;
  139.         }
  140.     }
  141.     if(linestate != FAIL && n != normlen && linestate != DONE) {
  142.         c = fgetc(ifp);
  143.         (void)ungetc(c, ifp);
  144.         if(lookup[c] == DONE) {
  145.         linestate = DONE;
  146.         }
  147.     }
  148.     if(linestate == FAIL || (n != normlen && linestate != DONE)) {
  149.         if(verbose && n > 0) {
  150.         *out = 0;
  151.         (void)fprintf(stderr, "Skip:%s\n", line);
  152.         }
  153.         if(readline()) {
  154.         continue;
  155.         } else {
  156.         break;
  157.         }
  158.     }
  159. skipcheck:
  160.     in = line;
  161.     do {
  162.         if((b6 = lookup[*in & 0xff]) >= 64) {
  163.         switch (b6) {
  164.         case DONE:
  165.             first = !first;
  166.             if(first) {
  167.             goto done;
  168.             }
  169.         case SKIP:
  170.             break;
  171.         default:
  172.             if(uneven_lines) {
  173.             break;
  174.             }
  175.             (void)fprintf(stderr, "bad char '%c'(%d)\n", *in, *in);
  176.             goto done;
  177.         }
  178.         } else {
  179.         /* Pack 6 bits to 8 bits */
  180.         switch (state68++) {
  181.         case 0:
  182.             b8 = b6<<2;
  183.             continue; /* No data byte */
  184.         case 1:
  185.             data = b8 | (b6>>4);
  186.             b8 = (b6&0xF) << 4;
  187.             break;
  188.         case 2:
  189.             data = b8 | (b6>>2);
  190.             b8 = (b6&0x3) << 6;
  191.             break;
  192.         case 3:
  193.             data = b8 | b6;
  194.             state68 = 0;
  195.             break;
  196.         }
  197.         if(!run) {
  198.             if(data == RUNCHAR) {
  199.             run = 1;
  200.             } else {
  201.             output(lastc = data);
  202.             }
  203.         }
  204.         else {
  205.             if(data == 0) {
  206.             output(lastc = RUNCHAR);
  207.             } else {
  208.             while(--data > 0) {
  209.                 output(lastc);
  210.             }
  211.             }
  212.             run = 0;
  213.         }
  214.         }
  215.     } while(++in < out);
  216.     if(!stop) {
  217.         if(!readline()) {
  218.         break;
  219.         }
  220.     }
  221.     }
  222. done:
  223.     oflush();
  224.     if(!stop && ostate != S_EXCESS) {
  225.     (void)fprintf(stderr, "premature EOF\n");
  226. #ifdef SCAN
  227.     do_error("hexbin: premature EOF");
  228. #endif /* SCAN */
  229.     exit(1);
  230.     }
  231.     end_put();
  232.     print_header2(verbose);
  233. }
  234.  
  235. static void get_header()
  236. {
  237.     int n;
  238.     unsigned long calc_crc, file_crc;
  239.  
  240.     _crc = INITCRC;            /* compute a crc for the header */
  241.  
  242.     for(n = 0; n < INFOBYTES; n++) {
  243.     info[n] = 0;
  244.     }
  245.     n = getq();            /* namelength */
  246.     n++;                /* must read trailing null also */
  247.     getqbuf(trname, n);        /* read name */
  248.     if(g_macname[0] == '\0') {
  249.     g_macname = trname;
  250.     }
  251.  
  252.     n = strlen(g_macname);
  253.     if(n > F_NAMELEN) {
  254.     n = F_NAMELEN;
  255.     }
  256.     (void)strncpy(mh.m_name, g_macname, n);
  257.     mh.m_name[n] = '\0';
  258.  
  259.     getqbuf(mh.m_type, 4);
  260.     getqbuf(mh.m_author, 4);
  261.     mh.m_flags = get2q();
  262.     mh.m_datalen = get4q();
  263.     mh.m_rsrclen = get4q();
  264.  
  265.     calc_crc = _crc;
  266.     file_crc = get2q();
  267.     verify_crc(calc_crc, file_crc);
  268.     if(listmode) {
  269.     (void)fprintf(stderr, "This file is in \"hqx\" format.\n");
  270.     }
  271.     transname(mh.m_name, trname, n);
  272.     define_name(trname);
  273.     print_header0(0);
  274.     print_header1(0, verbose);
  275.     info[I_NAMEOFF] = n;
  276.     (void)strncpy(info + I_NAMEOFF + 1, mh.m_name, n);
  277.     (void)strncpy(info + I_TYPEOFF, mh.m_type, 4);
  278.     (void)strncpy(info + I_AUTHOFF, mh.m_author, 4);
  279.     put2(info + I_FLAGOFF, (unsigned long)mh.m_flags);
  280.     put4(info + I_DLENOFF, (unsigned long)mh.m_datalen);
  281.     put4(info + I_RLENOFF, (unsigned long)mh.m_rsrclen);
  282.     put4(info + I_CTIMOFF, (unsigned long)mh.m_createtime);
  283.     put4(info + I_MTIMOFF, (unsigned long)mh.m_modifytime);
  284. }
  285.  
  286. static void oflush()
  287. {
  288.     int n, i;
  289.  
  290.     oq = obuf;
  291.     while(oq < op && !stop) {
  292.     switch (ostate) {
  293.     case S_HEADER:
  294.         get_header();
  295.         ++ostate;
  296.         break;
  297.     case S_DATAOPEN:
  298.         set_put(1);
  299.         todo = mh.m_datalen;
  300.         _crc = INITCRC;
  301.         ++ostate;
  302.         break;
  303.     case S_RSRCOPEN:
  304.         set_put(0);
  305.         todo = mh.m_rsrclen;
  306.         _crc = INITCRC;
  307.         ++ostate;
  308.         break;
  309.     case S_DATAWRITE:
  310.     case S_RSRCWRITE:
  311.         n = op-oq;
  312.         if(n > todo) {
  313.         n = todo;
  314.         }
  315.         for(i = 0; i < n; i++) {
  316.         put_byte((char)(oq[i]));
  317.         }
  318.         comp_q_crc_n(oq, oq+n);
  319.         oq += n;
  320.         todo -= n;
  321.         if(todo <= 0) {
  322.         ++ostate;
  323.         }
  324.         break;
  325.     case S_DATAC1:
  326.     case S_RSRCC1:
  327.         calc_crc = _crc;
  328.         file_crc = getq() << 8;
  329.         ++ostate;
  330.         break;
  331.     case S_DATAC2:
  332.     case S_RSRCC2:
  333.         /* Skip crc bytes */
  334.         file_crc |= getq();
  335.         verify_crc(calc_crc, file_crc);
  336.         ++ostate;
  337.         break;
  338.     case S_EXCESS:
  339.         (void)fprintf(stderr, "%d excess bytes ignored\n", op-oq);
  340.         oq = op;
  341.         break;
  342.     }
  343.     }
  344.     op = obuf;
  345. }
  346.  
  347. static int getq()
  348. {
  349.     int c;
  350.  
  351.     if(oq >= op) {
  352.     (void)fprintf(stderr, "premature EOF\n");
  353. #ifdef SCAN
  354.     do_error("hexbin: premature EOF");
  355. #endif /* SCAN */
  356.     exit(1);
  357.     }
  358.     c = *oq++ & 0xff;
  359.     comp_q_crc((unsigned)c);
  360.     return c;
  361. }
  362.  
  363. /* get2q(); q format -- read 2 bytes from input, return short */
  364. static long get2q()
  365. {
  366.     short high = getq() << 8;
  367.     return high | getq();
  368. }
  369.  
  370. /* get4q(); q format -- read 4 bytes from input, return long */
  371. static long get4q()
  372. {
  373.     int i;
  374.     long value = 0;
  375.  
  376.     for(i = 0; i < 4; i++) {
  377.     value = (value<<8) | getq();
  378.     }
  379.     return value;
  380. }
  381.  
  382. /* getqbuf(); q format -- read n characters from input into buf */
  383. static getqbuf(buf, n)
  384.     char *buf;
  385.     int n;
  386. {
  387.     int i;
  388.  
  389.     for(i = 0; i < n; i++) {
  390.     *buf++ = getq();
  391.     }
  392. }
  393. #else /* HQX */
  394. int hqx; /* keep lint and some compilers happy */
  395. #endif /* HQX */
  396.  
  397.