📄 hqx.c
字号:
#include "hexbin.h"#ifdef HQX#include "globals.h"#include "readline.h"#include "crc.h"#include "buffer.h"#include "../fileio/machdr.h"#include "../fileio/wrfile.h"#include "../util/util.h"#include "printhdr.h"extern void exit();static void get_header();static void oflush();static int getq();static long get2q();static long get4q();static getqbuf();static char *g_macname;/* New stuff which hopes to improve the speed. */#define RUNCHAR 0x90#define DONE 0x7F#define SKIP 0x7E#define FAIL 0x7Dstatic char lookup[256] = {/* ^@ ^A ^B ^C ^D ^E ^F ^G *//* 0*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,/* \b \t \n ^K ^L \r ^N ^O *//* 1*/ FAIL, FAIL, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL,/* ^P ^Q ^R ^S ^T ^U ^V ^W *//* 2*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,/* ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ *//* 3*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,/* ! " # $ % & ' *//* 4*/ FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,/* ( ) * + , - . / *//* 5*/ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, FAIL, FAIL,/* 0 1 2 3 4 5 6 7 *//* 6*/ 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, FAIL,/* 8 9 : ; < = > ? *//* 7*/ 0x14, 0x15, DONE, FAIL, FAIL, FAIL, FAIL, FAIL,/* @ A B C D E F G *//* 8*/ 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,/* H I J K L M N O *//* 9*/ 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, FAIL,/* P Q R S T U V W *//*10*/ 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, FAIL,/* X Y Z [ \ ] ^ _ *//*11*/ 0x2C, 0x2D, 0x2E, 0x2F, FAIL, FAIL, FAIL, FAIL,/* ` a b c d e f g *//*12*/ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, FAIL,/* h i j k l m n o *//*13*/ 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, FAIL, FAIL,/* p q r s t u v w *//*14*/ 0x3D, 0x3E, 0x3F, FAIL, FAIL, FAIL, FAIL, FAIL,/* x y z { | } ~ ^? *//*15*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,/*16*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,};static int stop = 0;static unsigned char obuf[BUFSIZ];static unsigned char *op = obuf;static unsigned char *oq;#define S_HEADER 0#define S_DATAOPEN 1#define S_DATAWRITE 2#define S_DATAC1 3#define S_DATAC2 4#define S_RSRCOPEN 5#define S_RSRCWRITE 6#define S_RSRCC1 7#define S_RSRCC2 8#define S_EXCESS 9static int ostate = S_HEADER;static unsigned long calc_crc;static unsigned long file_crc;static long todo;#define output(c) { *op++ = (c); if(op >= &obuf[BUFSIZ]) oflush(); }void hqx(macname)char *macname;{ int n, normlen, c; register char *in, *out; register int b6, b8, data, lastc = 0; char state68 = 0, run = 0, linestate, first = 1; g_macname = macname; ostate = S_HEADER; stop = 0; while(!stop) { n = strlen((char *)line); while(n > 0 && line[n - 1] == ' ') { n--; } out = line+n; if(uneven_lines) { goto skipcheck; } if(first) { normlen = n; } /* Check line for intermediate garbage */ linestate = SKIP; for(in = line; in < out; in++) { if((linestate = lookup[*in & 0xff]) == FAIL || ((linestate == DONE) && !first)) { break; } } if(linestate != FAIL && n != normlen && linestate != DONE) { c = fgetc(ifp); (void)ungetc(c, ifp); if(lookup[c] == DONE) { linestate = DONE; } } if(linestate == FAIL || (n != normlen && linestate != DONE)) { if(verbose && n > 0) { *out = 0; (void)fprintf(stderr, "Skip:%s\n", line); } if(readline()) { continue; } else { break; } }skipcheck: in = line; do { if((b6 = lookup[*in & 0xff]) >= 64) { switch (b6) { case DONE: first = !first; if(first) { goto done; } case SKIP: break; default: if(uneven_lines) { break; } (void)fprintf(stderr, "bad char '%c'(%d)\n", *in, *in); goto done; } } else { /* Pack 6 bits to 8 bits */ switch (state68++) { case 0: b8 = b6<<2; continue; /* No data byte */ case 1: data = b8 | (b6>>4); b8 = (b6&0xF) << 4; break; case 2: data = b8 | (b6>>2); b8 = (b6&0x3) << 6; break; case 3: data = b8 | b6; state68 = 0; break; } if(!run) { if(data == RUNCHAR) { run = 1; } else { output(lastc = data); } } else { if(data == 0) { output(lastc = RUNCHAR); } else { while(--data > 0) { output(lastc); } } run = 0; } } } while(++in < out); if(!stop) { if(!readline()) { break; } } }done: oflush(); if(!stop && ostate != S_EXCESS) { (void)fprintf(stderr, "premature EOF\n");#ifdef SCAN do_error("hexbin: premature EOF");#endif /* SCAN */ exit(1); } end_put(); print_header2(verbose);}static void get_header(){ int n; unsigned long calc_crc, file_crc; crc = INITCRC; /* compute a crc for the header */ for(n = 0; n < INFOBYTES; n++) { info[n] = 0; } n = getq(); /* namelength */ n++; /* must read trailing null also */ getqbuf(trname, n); /* read name */ if(g_macname[0] == '\0') { g_macname = trname; } n = strlen(g_macname); if(n > F_NAMELEN) { n = F_NAMELEN; } (void)strncpy(mh.m_name, g_macname, n); mh.m_name[n] = '\0'; getqbuf(mh.m_type, 4); getqbuf(mh.m_author, 4); mh.m_flags = get2q(); mh.m_datalen = get4q(); mh.m_rsrclen = get4q(); calc_crc = crc; file_crc = get2q(); verify_crc(calc_crc, file_crc); if(listmode) { (void)fprintf(stderr, "This file is in \"hqx\" format.\n"); } transname(mh.m_name, trname, n); define_name(trname); print_header0(0); print_header1(0, verbose); info[I_NAMEOFF] = n; (void)strncpy(info + I_NAMEOFF + 1, mh.m_name, n); (void)strncpy(info + I_TYPEOFF, mh.m_type, 4); (void)strncpy(info + I_AUTHOFF, mh.m_author, 4); put2(info + I_FLAGOFF, (unsigned long)mh.m_flags); put4(info + I_DLENOFF, (unsigned long)mh.m_datalen); put4(info + I_RLENOFF, (unsigned long)mh.m_rsrclen); put4(info + I_CTIMOFF, (unsigned long)mh.m_createtime); put4(info + I_MTIMOFF, (unsigned long)mh.m_modifytime);}static void oflush(){ int n, i; oq = obuf; while(oq < op && !stop) { switch (ostate) { case S_HEADER: get_header(); ++ostate; break; case S_DATAOPEN: set_put(1); todo = mh.m_datalen; crc = INITCRC; ++ostate; break; case S_RSRCOPEN: set_put(0); todo = mh.m_rsrclen; crc = INITCRC; ++ostate; break; case S_DATAWRITE: case S_RSRCWRITE: n = op-oq; if(n > todo) { n = todo; } for(i = 0; i < n; i++) { put_byte((char)(oq[i])); } comp_q_crc_n(oq, oq+n); oq += n; todo -= n; if(todo <= 0) { ++ostate; } break; case S_DATAC1: case S_RSRCC1: calc_crc = crc; file_crc = getq() << 8; ++ostate; break; case S_DATAC2: case S_RSRCC2: /* Skip crc bytes */ file_crc |= getq(); verify_crc(calc_crc, file_crc); ++ostate; break; case S_EXCESS: (void)fprintf(stderr, "%d excess bytes ignored\n", op-oq); oq = op; break; } } op = obuf;}static int getq(){ int c; if(oq >= op) { (void)fprintf(stderr, "premature EOF\n");#ifdef SCAN do_error("hexbin: premature EOF");#endif /* SCAN */ exit(1); } c = *oq++ & 0xff; comp_q_crc((unsigned)c); return c;}/* get2q(); q format -- read 2 bytes from input, return short */static long get2q(){ short high = getq() << 8; return high | getq();}/* get4q(); q format -- read 4 bytes from input, return long */static long get4q(){ int i; long value = 0; for(i = 0; i < 4; i++) { value = (value<<8) | getq(); } return value;}/* getqbuf(); q format -- read n characters from input into buf */static getqbuf(buf, n) char *buf; int n;{ int i; for(i = 0; i < n; i++) { *buf++ = getq(); }}#else /* HQX */int hqx; /* keep lint and some compilers happy */#endif /* HQX */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -