ttunpack.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /******************************************************************************
  2. *
  3. * project name: TI-68k Developer Utilities
  4. * file name: ttunpack.c
  5. * initial date: 18/08/2000
  6. * authors: albert@cs.tut.fi
  7. * thomas.nussbaumer@gmx.net
  8. * description: unpacking program
  9. *
  10. * -----------------------------------------------------------------------------
  11. *
  12. * based on code from Pasi 'Albert' Ojala, albert@cs.tut.fi
  13. *
  14. * heavily reduced to fit to the needs by thomas.nussbaumer@gmx.net
  15. *
  16. ******************************************************************************/
  17. /*
  18. This file is part of TI-68k Developer Utilities.
  19. This file is free software; you can redistribute it and/or
  20. modify it under the terms of the GNU Lesser General Public
  21. License as published by the Free Software Foundation; either
  22. version 2.1 of the License, or (at your option) any later version.
  23. As a special exception, UNMODIFIED copies of ttunpack may also be
  24. redistributed or sold without source code, for any purpose. (The Lesser
  25. General Public License restrictions do apply in other respects; for example,
  26. they cover modification of the program.) This exception notice must be
  27. removed on modified copies of this file.
  28. This program is distributed in the hope that it will be useful,
  29. but WITHOUT ANY WARRANTY; without even the implied warranty of
  30. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  31. Lesser General Public License for more details.
  32. You should have received a copy of the GNU Lesser General Public
  33. License along with this library; if not, write to the Free Software
  34. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  35. */
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include <ctype.h>
  40. #include "unpack.c"
  41. #include "tt.h" // generic defines
  42. #include "ttversion.h" // TI-68k Developer Utilities version info
  43. #include "revtools.h"
  44. #include "ttunpack.h" // errorcodes definition
  45. #include "packhead.h" // compressed header definition
  46. #ifdef FILE_REVISION
  47. #undef FILE_REVISION
  48. #endif
  49. #define FILE_REVISION "1.8"
  50. //=============================================================================
  51. // outputs usage information of this tool
  52. //=============================================================================
  53. void PrintUsage() {
  54. fprintf(USAGE_OUT, "Usage: ttunpack [-<flags>] <infile> <outfile>\n" \
  55. " -hti treat input as hex-text input\n" \
  56. " -hto generate hex-text output\n" \
  57. " -t just test (generates no outfile)\n");
  58. }
  59. #define NO_HEX_CHARACTER 255
  60. //=============================================================================
  61. // converts hex character to int
  62. //=============================================================================
  63. unsigned char hex2int(unsigned char c) {
  64. c = tolower(c);
  65. if (c >= 'a' && c <= 'f') return c - 'a' + 10;
  66. if (c >= '0' && c <= '9') return c - '0';
  67. return NO_HEX_CHARACTER;
  68. }
  69. //=============================================================================
  70. // converts hextext to binary
  71. //=============================================================================
  72. int ConvertText2Bin(unsigned char* ib,int origlen) {
  73. int pos;
  74. int cnt = 0;
  75. int searchforendofline = 0;
  76. int len_after_convert = 0;
  77. unsigned char val = 0; // 1.40: added initialization.
  78. unsigned char actual;
  79. len_after_convert = 0;
  80. for (pos = 0; pos < origlen;pos++) {
  81. if (searchforendofline) {
  82. if (ib[pos] == '\n') searchforendofline = 0;
  83. continue;
  84. }
  85. if (ib[pos] == '/') {
  86. cnt = 0;
  87. if (pos < origlen-1 && ib[pos+1] == '/') searchforendofline = 1;
  88. continue;
  89. }
  90. actual = hex2int(ib[pos]);
  91. if (actual == NO_HEX_CHARACTER) {
  92. cnt = 0;
  93. continue;
  94. }
  95. if (cnt == 0) {
  96. val = actual*16;
  97. cnt++;
  98. }
  99. else {
  100. val += actual;
  101. cnt=0;
  102. ib[len_after_convert++] = val;
  103. }
  104. }
  105. return(len_after_convert);
  106. }
  107. //=============================================================================
  108. // our main reason why we are here ...
  109. //=============================================================================
  110. int main(int argc, char* argv[]) {
  111. unsigned char* src;
  112. unsigned char* dest;
  113. FILE* fp;
  114. int result;
  115. PackedHeader* ch;
  116. int textinput = 0;
  117. int textoutput = 0;
  118. int justtest = 0;
  119. int i;
  120. int origsize;
  121. int bufsize;
  122. int newlen;
  123. int compsize;
  124. char* infilename = NULL;
  125. char* outfilename = NULL;
  126. PRINT_ID("TTUnpack");
  127. for (i=1;i<argc;i++) {
  128. if (!strcmp(argv[i], "-hti")) textinput = 1;
  129. else if (!strcmp(argv[i], "-hto")) textoutput = 1;
  130. else if (!strcmp(argv[i], "-t")) justtest = 1;
  131. else if (!infilename) infilename = argv[i];
  132. else if (!outfilename) outfilename = argv[i];
  133. else {
  134. PrintUsage();
  135. return 1;
  136. }
  137. }
  138. //-------------------------------------------
  139. // check if infile and out file are specified
  140. //-------------------------------------------
  141. if (!infilename || (!justtest && !outfilename)) {
  142. PrintUsage();
  143. return 1;
  144. }
  145. //----------------------------------------------------------------
  146. // NOTE: The code is prepared to handle piping, but piping doesn't
  147. // work correct in all cases on a Win98 system, so I have
  148. // disabled it
  149. //----------------------------------------------------------------
  150. if (infilename) {
  151. if (!(fp = fopen(infilename, "rb"))) {
  152. fprintf(stderr, "ERROR: cannot open input file %s\n", infilename);
  153. return 1;
  154. }
  155. }
  156. else {
  157. fprintf(stderr, "assuming stdin as text input.\nCtrl-C to abort, Ctrl-Z for EOF.\n");
  158. fp = stdin;
  159. }
  160. /* Read in the data */
  161. compsize = 0;
  162. bufsize = 0;
  163. src = NULL;
  164. while (1) {
  165. if (bufsize < compsize + 1024) {
  166. unsigned char *tmp = realloc(src, bufsize + 1024);
  167. if (!tmp) {
  168. fprintf(stderr, "ERROR: cannot allocate buffer\n");
  169. free(src);
  170. if (infilename) fclose(fp);
  171. return 1;
  172. }
  173. src = tmp;
  174. bufsize += 1024;
  175. }
  176. newlen = fread(src + compsize, 1, 1024, fp);
  177. if (newlen <= 0) break;
  178. compsize += newlen;
  179. }
  180. if (infilename) fclose(fp);
  181. //-----------------------------------------------------------
  182. // convert the input buffer from hex text to binary
  183. // if the user asks for it
  184. //-----------------------------------------------------------
  185. if (textinput) compsize = ConvertText2Bin(src,compsize);
  186. if (compsize > 65535) {
  187. fprintf(stderr, "ERROR: inputdata is too long (>65535 bytes)\n");
  188. free(src);
  189. return 1;
  190. }
  191. ch = (PackedHeader*)src;
  192. if ((compsize != (ch->compsize_lo | (ch->compsize_hi << 8))) ||
  193. ch->magic1 != MAGIC_CHAR1 ||
  194. ch->magic2 != MAGIC_CHAR2)
  195. {
  196. fprintf(stderr, "ERROR: format mismatch in input (csize=%d|m1=%c|m2=%c)\n",
  197. compsize,ch->magic1,ch->magic2);
  198. free(src);
  199. return 1;
  200. }
  201. origsize = ch->origsize_lo | (ch->origsize_hi << 8);
  202. if (!(dest = (unsigned char*)malloc(origsize))) {
  203. fputs("ERROR: cannot allocate output buffer\n",stderr);
  204. free(src);
  205. return 1;
  206. }
  207. result=UnPack(src,dest);
  208. if (result) {
  209. fprintf(stderr,"ERROR: cannot decompress (code %03d)\n",result);
  210. free(src);
  211. free(dest);
  212. return 1;
  213. }
  214. if (!justtest) {
  215. if ((outfilename && (fp = fopen(outfilename, "wb"))) || (fp = stdout)) {
  216. if (textoutput) {
  217. int loopy;
  218. for (loopy=0;loopy<origsize;loopy++) {
  219. if (loopy < origsize - 1) fprintf(fp,"0x%02x,",dest[loopy]);
  220. else fprintf(fp,"0x%02x",dest[loopy]);
  221. if (loopy && (!(loopy % DEFAULT_ITEMS_PER_LINE))) fputc('\n',fp);
  222. }
  223. }
  224. else {
  225. fwrite(dest, origsize, 1, fp);
  226. if (outfilename) fclose(fp);
  227. fprintf(stderr,"Decompressed %u bytes.\n\n",origsize);
  228. }
  229. result = 0;
  230. if (fp != stdout) fclose(fp);
  231. }
  232. else {
  233. fprintf(stderr,"ERROR: cannot open outputfile %s\n\n",outfilename);
  234. result = 1;
  235. }
  236. }
  237. free(src);
  238. free(dest);
  239. return result;
  240. }
  241. //#############################################################################
  242. //###################### NO MORE FAKES BEYOND THIS LINE #######################
  243. //#############################################################################
  244. //
  245. //=============================================================================
  246. // Revision History
  247. //=============================================================================
  248. //
  249. // Revision 1.8 2009/01/25 Lionel Debroux
  250. // Changes by Romain Liévin and/or me for 64-bit compatibility.
  251. // Adapt to new version display (revtools.h).
  252. //
  253. // Revision 1.7 2002/02/13 17:03:18 tnussb
  254. // -t option fixed
  255. //
  256. // Revision 1.6 2002/02/07 09:49:38 tnussb
  257. // all local includes changed, because header files are now located in pctools folder
  258. //
  259. // Revision 1.5 2001/02/05 20:46:02 Thomas Nussbaumer
  260. // using now local unpack.c file instead shared one
  261. //
  262. // Revision 1.4 2000/11/28 00:05:12 Thomas Nussbaumer
  263. // using now USAGE_OUT stream for usage info
  264. //
  265. // Revision 1.3 2000/08/23 20:25:43 Thomas Nussbaumer
  266. // adapted to automatic version display (revtools.h)
  267. //
  268. // Revision 1.2 2000/08/20 15:31:58 Thomas Nussbaumer
  269. // (1) using now shared unpack.c file
  270. // (2) flag -t added (just test, no output generation)
  271. //
  272. // Revision 1.1 2000/08/18 20:19:51 Thomas Nussbaumer
  273. // initial version
  274. //
  275. //