1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * cws2fws by Alex Beregszaszi 3cabdff1aSopenharmony_ci * This file is placed in the public domain. 4cabdff1aSopenharmony_ci * Use the program however you see fit. 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This utility converts compressed Macromedia Flash files to uncompressed ones. 7cabdff1aSopenharmony_ci */ 8cabdff1aSopenharmony_ci 9cabdff1aSopenharmony_ci#include "config.h" 10cabdff1aSopenharmony_ci#include <sys/stat.h> 11cabdff1aSopenharmony_ci#include <fcntl.h> 12cabdff1aSopenharmony_ci#include <stdio.h> 13cabdff1aSopenharmony_ci#include <stdlib.h> 14cabdff1aSopenharmony_ci#if HAVE_UNISTD_H 15cabdff1aSopenharmony_ci#include <unistd.h> 16cabdff1aSopenharmony_ci#endif 17cabdff1aSopenharmony_ci#if HAVE_IO_H 18cabdff1aSopenharmony_ci#include <io.h> 19cabdff1aSopenharmony_ci#endif 20cabdff1aSopenharmony_ci#include <zlib.h> 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci#ifdef DEBUG 23cabdff1aSopenharmony_ci#define dbgprintf printf 24cabdff1aSopenharmony_ci#else 25cabdff1aSopenharmony_ci#define dbgprintf(...) do { if (0) printf(__VA_ARGS__); } while (0) 26cabdff1aSopenharmony_ci#endif 27cabdff1aSopenharmony_ci 28cabdff1aSopenharmony_ciint main(int argc, char *argv[]) 29cabdff1aSopenharmony_ci{ 30cabdff1aSopenharmony_ci int fd_in, fd_out, comp_len, uncomp_len, i, last_out; 31cabdff1aSopenharmony_ci char buf_in[1024], buf_out[65536]; 32cabdff1aSopenharmony_ci z_stream zstream; 33cabdff1aSopenharmony_ci struct stat statbuf; 34cabdff1aSopenharmony_ci int ret = 1; 35cabdff1aSopenharmony_ci 36cabdff1aSopenharmony_ci if (argc < 3) { 37cabdff1aSopenharmony_ci printf("Usage: %s <infile.swf> <outfile.swf>\n", argv[0]); 38cabdff1aSopenharmony_ci return 1; 39cabdff1aSopenharmony_ci } 40cabdff1aSopenharmony_ci 41cabdff1aSopenharmony_ci fd_in = open(argv[1], O_RDONLY); 42cabdff1aSopenharmony_ci if (fd_in < 0) { 43cabdff1aSopenharmony_ci perror("Error opening input file"); 44cabdff1aSopenharmony_ci return 1; 45cabdff1aSopenharmony_ci } 46cabdff1aSopenharmony_ci 47cabdff1aSopenharmony_ci fd_out = open(argv[2], O_WRONLY | O_CREAT, 00644); 48cabdff1aSopenharmony_ci if (fd_out < 0) { 49cabdff1aSopenharmony_ci perror("Error opening output file"); 50cabdff1aSopenharmony_ci close(fd_in); 51cabdff1aSopenharmony_ci return 1; 52cabdff1aSopenharmony_ci } 53cabdff1aSopenharmony_ci 54cabdff1aSopenharmony_ci if (read(fd_in, &buf_in, 8) != 8) { 55cabdff1aSopenharmony_ci printf("Header error\n"); 56cabdff1aSopenharmony_ci goto out; 57cabdff1aSopenharmony_ci } 58cabdff1aSopenharmony_ci 59cabdff1aSopenharmony_ci if (buf_in[0] != 'C' || buf_in[1] != 'W' || buf_in[2] != 'S') { 60cabdff1aSopenharmony_ci printf("Not a compressed flash file\n"); 61cabdff1aSopenharmony_ci goto out; 62cabdff1aSopenharmony_ci } 63cabdff1aSopenharmony_ci 64cabdff1aSopenharmony_ci if (fstat(fd_in, &statbuf) < 0) { 65cabdff1aSopenharmony_ci perror("fstat failed"); 66cabdff1aSopenharmony_ci return 1; 67cabdff1aSopenharmony_ci } 68cabdff1aSopenharmony_ci comp_len = statbuf.st_size; 69cabdff1aSopenharmony_ci uncomp_len = buf_in[4] | (buf_in[5] << 8) | (buf_in[6] << 16) | (buf_in[7] << 24); 70cabdff1aSopenharmony_ci 71cabdff1aSopenharmony_ci printf("Compressed size: %d Uncompressed size: %d\n", 72cabdff1aSopenharmony_ci comp_len - 4, uncomp_len - 4); 73cabdff1aSopenharmony_ci 74cabdff1aSopenharmony_ci // write out modified header 75cabdff1aSopenharmony_ci buf_in[0] = 'F'; 76cabdff1aSopenharmony_ci if (write(fd_out, &buf_in, 8) < 8) { 77cabdff1aSopenharmony_ci perror("Error writing output file"); 78cabdff1aSopenharmony_ci goto out; 79cabdff1aSopenharmony_ci } 80cabdff1aSopenharmony_ci 81cabdff1aSopenharmony_ci zstream.zalloc = NULL; 82cabdff1aSopenharmony_ci zstream.zfree = NULL; 83cabdff1aSopenharmony_ci zstream.opaque = NULL; 84cabdff1aSopenharmony_ci if (inflateInit(&zstream) != Z_OK) { 85cabdff1aSopenharmony_ci fprintf(stderr, "inflateInit failed\n"); 86cabdff1aSopenharmony_ci return 1; 87cabdff1aSopenharmony_ci } 88cabdff1aSopenharmony_ci 89cabdff1aSopenharmony_ci for (i = 0; i < comp_len - 8;) { 90cabdff1aSopenharmony_ci int ret, len = read(fd_in, &buf_in, 1024); 91cabdff1aSopenharmony_ci 92cabdff1aSopenharmony_ci if (len == -1) { 93cabdff1aSopenharmony_ci printf("read failure\n"); 94cabdff1aSopenharmony_ci inflateEnd(&zstream); 95cabdff1aSopenharmony_ci goto out; 96cabdff1aSopenharmony_ci } 97cabdff1aSopenharmony_ci 98cabdff1aSopenharmony_ci dbgprintf("read %d bytes\n", len); 99cabdff1aSopenharmony_ci 100cabdff1aSopenharmony_ci last_out = zstream.total_out; 101cabdff1aSopenharmony_ci 102cabdff1aSopenharmony_ci zstream.next_in = &buf_in[0]; 103cabdff1aSopenharmony_ci zstream.avail_in = len; 104cabdff1aSopenharmony_ci zstream.next_out = &buf_out[0]; 105cabdff1aSopenharmony_ci zstream.avail_out = 65536; 106cabdff1aSopenharmony_ci 107cabdff1aSopenharmony_ci ret = inflate(&zstream, Z_SYNC_FLUSH); 108cabdff1aSopenharmony_ci if (ret != Z_STREAM_END && ret != Z_OK) { 109cabdff1aSopenharmony_ci printf("Error while decompressing: %d\n", ret); 110cabdff1aSopenharmony_ci inflateEnd(&zstream); 111cabdff1aSopenharmony_ci goto out; 112cabdff1aSopenharmony_ci } 113cabdff1aSopenharmony_ci 114cabdff1aSopenharmony_ci dbgprintf("a_in: %d t_in: %lu a_out: %d t_out: %lu -- %lu out\n", 115cabdff1aSopenharmony_ci zstream.avail_in, zstream.total_in, zstream.avail_out, 116cabdff1aSopenharmony_ci zstream.total_out, zstream.total_out - last_out); 117cabdff1aSopenharmony_ci 118cabdff1aSopenharmony_ci if (write(fd_out, &buf_out, zstream.total_out - last_out) < 119cabdff1aSopenharmony_ci zstream.total_out - last_out) { 120cabdff1aSopenharmony_ci perror("Error writing output file"); 121cabdff1aSopenharmony_ci inflateEnd(&zstream); 122cabdff1aSopenharmony_ci goto out; 123cabdff1aSopenharmony_ci } 124cabdff1aSopenharmony_ci 125cabdff1aSopenharmony_ci i += len; 126cabdff1aSopenharmony_ci 127cabdff1aSopenharmony_ci if (ret == Z_STREAM_END || ret == Z_BUF_ERROR) 128cabdff1aSopenharmony_ci break; 129cabdff1aSopenharmony_ci } 130cabdff1aSopenharmony_ci 131cabdff1aSopenharmony_ci if (zstream.total_out != uncomp_len - 8) { 132cabdff1aSopenharmony_ci printf("Size mismatch (%lu != %d), updating header...\n", 133cabdff1aSopenharmony_ci zstream.total_out, uncomp_len - 8); 134cabdff1aSopenharmony_ci 135cabdff1aSopenharmony_ci buf_in[0] = (zstream.total_out + 8) & 0xff; 136cabdff1aSopenharmony_ci buf_in[1] = ((zstream.total_out + 8) >> 8) & 0xff; 137cabdff1aSopenharmony_ci buf_in[2] = ((zstream.total_out + 8) >> 16) & 0xff; 138cabdff1aSopenharmony_ci buf_in[3] = ((zstream.total_out + 8) >> 24) & 0xff; 139cabdff1aSopenharmony_ci 140cabdff1aSopenharmony_ci if ( lseek(fd_out, 4, SEEK_SET) < 0 141cabdff1aSopenharmony_ci || write(fd_out, &buf_in, 4) < 4) { 142cabdff1aSopenharmony_ci perror("Error writing output file"); 143cabdff1aSopenharmony_ci inflateEnd(&zstream); 144cabdff1aSopenharmony_ci goto out; 145cabdff1aSopenharmony_ci } 146cabdff1aSopenharmony_ci } 147cabdff1aSopenharmony_ci 148cabdff1aSopenharmony_ci ret = 0; 149cabdff1aSopenharmony_ci inflateEnd(&zstream); 150cabdff1aSopenharmony_ciout: 151cabdff1aSopenharmony_ci close(fd_in); 152cabdff1aSopenharmony_ci close(fd_out); 153cabdff1aSopenharmony_ci return ret; 154cabdff1aSopenharmony_ci} 155