/* -> c.squashff * Test harness for the file to file and other variants of * the LZW compression/decompression. * Copyright (C) 1991 J.G.Thackray */ #include #include #include #include #include "kernel.h" #define Compress_CompressStoreStore 0x42700 #define Compress_DecompressStoreStore 0x42701 #define Compress_CompressStoreFile 0x42702 #define Compress_DecompressStoreFile 0x42703 #define Compress_CompressFileStore 0x42704 #define Compress_DecompressFileStore 0x42705 #define Compress_CompressFileFile 0x42706 #define Compress_DecompressFileFile 0x42707 #define Compress_CompressStoreStoreFast 0x42708 #define Compress_DecompressStoreStoreFast 0x42709 #define USAGE "Usage: squashff [-z] filename filename" int main(int argc, char *argv[]) { int bad = 1; int do_compress = 1; if (argc == 3 || argc == 4) { argv++; for (;;) { int riscos_input, riscos_output, i; _kernel_swi_regs r; _kernel_oserror *err; FILE *input, *output; #define workspace_size 0x8000 char *workspace = malloc(workspace_size); char *output_store, *output_store_temp, *input_store; long input_size, output_size; if (argc == 4) { if (strlen(*argv) == 2 && argv[0][0] == '-' && tolower(argv[0][1]) == 'z') { do_compress = 0; argv++; } else { break; }; }; /* Test file to file algorithm */ printf("Testing %sompressFileFile\n", (do_compress) ? "C" : "Dec"); riscos_input = _kernel_osfind(0x4f, *argv); err = _kernel_last_oserror(); if (err || !riscos_input) { fprintf(stderr, "squashff: cannot open '%s' for input\n", *argv); if (err) fprintf(stderr, "squashff: error was (0x%x), '%s'\n", err->errnum, err->errmess); break; }; riscos_output = _kernel_osfind(0x83, argv[1]); err = _kernel_last_oserror(); if (err || !riscos_output) { (void)_kernel_osfind(0, (char *)riscos_input); /* Close the input */ fprintf(stderr, "squashff: cannot open '%s' for output\n", argv[1]); if (err) fprintf(stderr, "squashff: error was (0x%x), '%s'\n", err->errnum, err->errmess); break; }; r.r[0] = (int)workspace; r.r[1] = workspace_size; r.r[2] = riscos_input; r.r[4] = riscos_output; r.r[6] = 0; err = (do_compress) ? _kernel_swi(Compress_CompressFileFile, &r, &r) : _kernel_swi(Compress_DecompressFileFile, &r, &r); (void)_kernel_osfind(0, (char *)riscos_input); (void)_kernel_osfind(0, (char *)riscos_output); if (err) { fprintf(stderr, "squashff: %s failed: error (0x%x) '%s'\n", (do_compress) ? "Compress" : "Decompress", err->errnum, err->errmess); break; }; err = _kernel_last_oserror(); if (err) { fprintf(stderr, "squashff: cannot close files: error (0x%x) '%s'\n", err->errnum, err->errmess); break; }; /* Now try using file to store algorithm */ printf("Testing %sompressFileStore\n", (do_compress) ? "C" : "Dec"); output = fopen(argv[1], "r"); /* Already written by above */ if (!output) { fprintf(stderr, "Cannot reopen '%s' for input\n", argv[1]); break; }; fseek(output, 0, SEEK_END); output_size = ftell(output); output_store = malloc((size_t)output_size); fseek(output, 0, SEEK_SET); if (fread(output_store, 1, (size_t)output_size, output) != output_size) { fprintf(stderr, "Cannot read all of '%s' for input\n", argv[1]); fclose(output); break; }; fclose(output); riscos_input = _kernel_osfind(0x4f, *argv); err = _kernel_last_oserror(); if (err || !riscos_input) { fprintf(stderr, "squashff: cannot open '%s' for input\n", *argv); if (err) fprintf(stderr, "squashff: error was (0x%x), '%s'\n", err->errnum, err->errmess); break; }; output_store_temp = malloc((size_t)output_size); r.r[0] = (int)workspace; r.r[1] = workspace_size; r.r[2] = riscos_input; r.r[4] = (int)output_store_temp; r.r[5] = (int)output_size; r.r[6] = 0; err = (do_compress) ? _kernel_swi(Compress_CompressFileStore, &r, &r) : _kernel_swi(Compress_DecompressFileStore, &r, &r); (void)_kernel_osfind(0, (char *)riscos_input); if (err) { fprintf(stderr, "squashff: %s failed: error (0x%x) '%s'\n", (do_compress) ? "Compress" : "Decompress", err->errnum, err->errmess); break; }; if (do_compress && r.r[0] != 0) { fprintf(stderr, "squashff: CompressFileStore fails to complete\n"); break; }; if (r.r[5] != output_size) { fprintf(stderr, "squashff: %s fails to produce correct amount of output\nShould produce 0x%lx, but produced 0x%x\n", (do_compress) ? "Compress" : "Decompress", output_size, r.r[5]); break; }; if (memcmp(output_store, output_store_temp, (size_t)output_size)) { fprintf(stderr, "squashff: CompressFileStore comparison error\n"); break; }; /* Now try file to store restartability on compression */ if (do_compress) { int i = 0; printf("Testing CompressFileStore restartability\n"); while (i < output_size) output_store_temp[i++] = 0; /* Clear the output */ riscos_input = _kernel_osfind(0x4f, *argv); err = _kernel_last_oserror(); if (err || !riscos_input) { fprintf(stderr, "squashff: cannot open '%s' for input\n", *argv); if (err) fprintf(stderr, "squashff: error was (0x%x), '%s'\n", err->errnum, err->errmess); break; }; r.r[0] = (int)workspace; r.r[1] = workspace_size; r.r[2] = riscos_input; r.r[4] = (int)output_store_temp; r.r[5] = (int)(output_size/2); r.r[6] = 0; /* From scratch */ err = _kernel_swi(Compress_CompressFileStore, &r, &r); if (err) { fprintf(stderr, "squashff: Compress failed: error (0x%x) '%s'\n", err->errnum, err->errmess); (void)_kernel_osfind(0, (char *)riscos_input); break; }; if (r.r[0] != 0) { /* printf("squashff: CompressFileStore fails to complete first time, continuing\n"); printf("squashff: output size used 0x%x\n", r.r[5]); */ r.r[0] = (int)workspace; r.r[1] = workspace_size; r.r[2] = riscos_input; r.r[4] = (int)output_store_temp + r.r[5]; r.r[5] = (int)(output_size); /* Full size */ r.r[6] = 1; /* From workspace */ err = _kernel_swi(Compress_CompressFileStore, &r, &r); (void)_kernel_osfind(0, (char *)riscos_input); if (err) { fprintf(stderr, "squashff: CompressFileStore failed: error (0x%x) '%s'\n", err->errnum, err->errmess); break; }; if (r.r[0] != 0) { fprintf(stderr, "squashff: CompressFileStore fails to complete second time\n"); break; }; } else { printf("squashff: CompressFileStore completes first time?\n"); }; if (r.r[5] != output_size) { fprintf(stderr, "squashff: CompressFileStore fails to produce correct amount of output\nShould produce 0x%lx, but produced 0x%x\n", output_size, r.r[5]); break; }; if (memcmp(output_store, output_store_temp, (size_t)output_size)) { fprintf(stderr, "squashff: CompressFileStore comparison error\n"); break; }; }; /* Now try using store to store algorithm */ printf("Testing %sompressStoreStore\n", (do_compress) ? "C" : "Dec"); i = 0; while (i < output_size) output_store_temp[i++] = 0; /* Clear the output buffer */ input = fopen(argv[0], "r"); if (!output) { fprintf(stderr, "Cannot reopen '%s' for input\n", argv[0]); break; }; fseek(input, 0, SEEK_END); input_size = ftell(input); input_store = malloc((size_t)input_size); fseek(input, 0, SEEK_SET); if (fread(input_store, 1, (size_t)input_size, input) != input_size) { fprintf(stderr, "Cannot read all of '%s' for input\n", argv[0]); fclose(input); break; }; fclose(input); r.r[0] = (int)workspace; r.r[1] = workspace_size; r.r[2] = (int)input_store; r.r[3] = (int)input_size; r.r[4] = (int)output_store_temp; r.r[5] = (int)output_size; r.r[6] = 0; /* From scratch, no more input if decompress */ err = (do_compress) ? _kernel_swi(Compress_CompressStoreStore, &r, &r) : _kernel_swi(Compress_DecompressStoreStore, &r, &r); if (err) { fprintf(stderr, "squashff: %s failed: error (0x%x) '%s'\n", (do_compress) ? "Compress" : "Decompress", err->errnum, err->errmess); break; }; if (r.r[0] != 0) { fprintf(stderr, "squashff: %s fails to complete, r0 = 0x%x, r3 = 0x%x, input_size = 0x%lx\n", (do_compress) ? "Compress" : "Decompress", r.r[0], r.r[3], input_size); break; }; if (r.r[5] != output_size) { fprintf(stderr, "squashff: %s fails to produce correct amount of output\nShould produce 0x%lx, but produced 0x%x\n", (do_compress) ? "Compress" : "Decompress", output_size, r.r[5]); break; }; if (memcmp(output_store, output_store_temp, (size_t)output_size)) { fprintf(stderr, "squashff: CompressStoreStore comparison error\n"); break; }; /* Now try store to store restartability on compression */ if (do_compress) { int i = 0; printf("Testing CompressStoreStore restartibility\n"); while (i < output_size) output_store_temp[i++] = 0; /* Clear the output */ r.r[0] = (int)workspace; r.r[1] = workspace_size; r.r[2] = (int)input_store; r.r[3] = (int)input_size; r.r[4] = (int)output_store_temp; r.r[5] = (int)(output_size/2); r.r[6] = 0; /* From scratch */ err = _kernel_swi(Compress_CompressStoreStore, &r, &r); if (err) { fprintf(stderr, "squashff: Compress failed: error (0x%x) '%s'\n", err->errnum, err->errmess); break; }; if (r.r[0] != 0) { /* printf("squashff: CompressStoreStore fails to complete first time, continuing\n"); printf("squashff: input size used 0x%x\noutput size used 0x%x\n", r.r[3], r.r[5]); */ r.r[0] = (int)workspace; r.r[1] = workspace_size; r.r[2] = (int)input_store + r.r[3]; r.r[3] = (int)input_size; /* Should be ignored */ r.r[4] = (int)output_store_temp + r.r[5]; r.r[5] = (int)(output_size); /* Full size */ r.r[6] = 1; /* From workspace */ err = _kernel_swi(Compress_CompressStoreStore, &r, &r); if (err) { fprintf(stderr, "squashff: CompressStoreStore failed: error (0x%x) '%s'\n", err->errnum, err->errmess); break; }; if (r.r[0] != 0) { fprintf(stderr, "squashff: CompressStoreStore fails to complete second time\n"); break; }; } else { printf("squashff: CompressStoreStore completes first time?\n"); }; if (r.r[5] != output_size) { fprintf(stderr, "squashff: CompressStoreStore fails to produce correct amount of output\nShould produce 0x%lx, but produced 0x%x\n", output_size, r.r[5]); break; }; if (memcmp(output_store, output_store_temp, (size_t)output_size)) { fprintf(stderr, "squashff: CompressStoreStore comparison error\n"); break; }; }; /* Now try store to store restartability on decompression */ if (!do_compress) { int i = 0; printf("Testing DecompressStoreStore restartibility\n"); while (i < output_size) output_store_temp[i++] = 0; /* Clear the output */ r.r[0] = (int)workspace; r.r[1] = workspace_size; r.r[2] = (int)input_store; r.r[3] = (int)(input_size/2); r.r[4] = (int)output_store_temp; r.r[5] = (int)output_size; r.r[6] = 1; /* From scratch, allow continuation */ err = _kernel_swi(Compress_DecompressStoreStore, &r, &r); if (err) { fprintf(stderr, "squashff: Decompress failed: error (0x%x) '%s'\n", err->errnum, err->errmess); break; }; if (r.r[0] != 0) { /* printf("squashff: DeompressStoreStore fails to complete first time, continuing\n"); printf("squashff: input size remaining 0x%x\noutput size used 0x%x\n", r.r[3], r.r[5]); */ r.r[0] = (int)workspace; r.r[1] = workspace_size; r.r[2] = (int)input_store + (int)(input_size/2) - r.r[3]; r.r[3] += (int)(input_size/4); r.r[4] = (int)output_store_temp + r.r[5]; r.r[5] = (int)output_size; r.r[6] = 3; /* From workspace, continue when run out */ err = _kernel_swi(Compress_DecompressStoreStore, &r, &r); if (err) { fprintf(stderr, "squashff: DecompressStoreStore failed: error (0x%x) '%s'\n", err->errnum, err->errmess); break; }; if (r.r[0] != 0) { /* printf("squashff: DeompressStoreStore fails to complete second time, continuing\n"); printf("squashff: input size remaining 0x%x\noutput size used 0x%x\n", r.r[3], r.r[5]); */ r.r[0] = (int)workspace; r.r[1] = workspace_size; r.r[2] = (int)input_store + (int)(input_size/2) + (int)(input_size/4) - r.r[3]; r.r[3] += (int)input_size - (int)(input_size/2) - (int)(input_size/4); r.r[4] = (int)output_store_temp + r.r[5]; r.r[5] = (int)output_size; r.r[6] = 2; /* From workspace, terminate when run out */ err = _kernel_swi(Compress_DecompressStoreStore, &r, &r); if (err) { fprintf(stderr, "squashff: DecompressStoreStore failed: error (0x%x) '%s'\n", err->errnum, err->errmess); break; }; if (r.r[0] != 0) { fprintf(stderr, "squashff: DecompressStoreStore fails to complete third time\n"); break; }; } else { printf("squashff: DecompressStoreStore completes second time?\n"); }; } else { printf("squashff: DecompressStoreStore completes first time?\n"); }; if (r.r[5] != output_size) { fprintf(stderr, "squashff: DecompressStoreStore fails to produce correct amount of output\nShould produce 0x%lx, but produced 0x%x\n", output_size, r.r[5]); break; }; if (memcmp(output_store, output_store_temp, (size_t)output_size)) { fprintf(stderr, "squashff: DecompressStoreStore comparison error\n"); break; }; }; /* Now try using store to file algorithm */ printf("Testing %sompressStoreFile\n", (do_compress) ? "C" : "Dec"); riscos_output = _kernel_osfind(0x83, argv[1]); err = _kernel_last_oserror(); if (err || !riscos_output) { fprintf(stderr, "squashff: cannot open '%s' for output\n", argv[1]); if (err) fprintf(stderr, "squashff: error was (0x%x), '%s'\n", err->errnum, err->errmess); break; }; r.r[0] = (int)workspace; r.r[1] = workspace_size; r.r[2] = (int)input_store; r.r[3] = (int)input_size; r.r[4] = riscos_output; r.r[6] = 0; /* From scratch, no more input */ err = (do_compress) ? _kernel_swi(Compress_CompressStoreFile, &r, &r) : _kernel_swi(Compress_DecompressStoreFile, &r, &r); (void)_kernel_osfind(0, (char *)riscos_output); if (err) { fprintf(stderr, "squashff: %s failed: error (0x%x) '%s'\n", (do_compress) ? "Compress" : "Decompress", err->errnum, err->errmess); break; }; output = fopen(argv[1], "r"); /* Already written by above */ if (!output) { fprintf(stderr, "Cannot reopen '%s' for input\n", argv[1]); break; }; fseek(output, 0, SEEK_END); if (output_size != ftell(output)) { fprintf(stderr, "%s produces incorrect output size, should be 0x%lx but was 0x%lx\n", (do_compress) ? "Compress" : "Decompress", output_size, ftell(output)); fclose(output); break; }; fseek(output, 0, SEEK_SET); if (fread(output_store_temp, 1, (size_t)output_size, output) != output_size) { fprintf(stderr, "Cannot read all of '%s' for input\n", argv[1]); fclose(output); break; }; fclose(output); if (memcmp(output_store, output_store_temp, (size_t)output_size)) { fprintf(stderr, "squashff: CompressFileStore comparison error\n"); break; }; /* Now try store to file restartability on decompression */ if (!do_compress) { int i = 0; printf("Testing DecompressStoreFile restartibility\n"); while (i < output_size) output_store_temp[i++] = 0; /* Clear the output */ riscos_output = _kernel_osfind(0x83, argv[1]); err = _kernel_last_oserror(); if (err || !riscos_output) { fprintf(stderr, "squashff: cannot open '%s' for output\n", argv[1]); if (err) fprintf(stderr, "squashff: error was (0x%x), '%s'\n", err->errnum, err->errmess); break; }; r.r[0] = (int)workspace; r.r[1] = workspace_size; r.r[2] = (int)input_store; r.r[3] = (int)(input_size/2); r.r[4] = riscos_output; r.r[6] = 1; /* From scratch, allow continuation */ err = _kernel_swi(Compress_DecompressStoreFile, &r, &r); if (err) { fprintf(stderr, "squashff: Decompress failed: error (0x%x) '%s'\n", err->errnum, err->errmess); (void)_kernel_osfind(0, (char *)riscos_output); break; }; if (r.r[0] != 0) { /* printf("squashff: DeompressStoreFile fails to complete first time, continuing\n"); printf("squashff: input size remaining 0x%x\noutput size used 0x%x\n", r.r[3], r.r[5]); */ r.r[0] = (int)workspace; r.r[1] = workspace_size; r.r[2] = (int)input_store + (int)(input_size/2) - r.r[3]; r.r[3] += (int)(input_size/4); r.r[4] = riscos_output; r.r[6] = 3; /* From workspace, continue when run out */ err = _kernel_swi(Compress_DecompressStoreFile, &r, &r); if (err) { fprintf(stderr, "squashff: DecompressStoreFile failed: error (0x%x) '%s'\n", err->errnum, err->errmess); (void)_kernel_osfind(0, (char *)riscos_output); break; }; if (r.r[0] != 0) { /* printf("squashff: DeompressStoreFile fails to complete second time, continuing\n"); printf("squashff: input size remaining 0x%x\noutput size used 0x%x\n", r.r[3], r.r[5]); */ r.r[0] = (int)workspace; r.r[1] = workspace_size; r.r[2] = (int)input_store + (int)(input_size/2) + (int)(input_size/4) - r.r[3]; r.r[3] += (int)input_size - (int)(input_size/2) - (int)(input_size/4); r.r[4] = riscos_output; r.r[6] = 2; /* From workspace, terminate when run out */ err = _kernel_swi(Compress_DecompressStoreFile, &r, &r); if (err) { fprintf(stderr, "squashff: DecompressStoreFile failed: error (0x%x) '%s'\n", err->errnum, err->errmess); (void)_kernel_osfind(0, (char *)riscos_output); break; }; if (r.r[0] != 0) { fprintf(stderr, "squashff: DecompressStoreFile fails to complete third time\n"); (void)_kernel_osfind(0, (char *)riscos_output); break; }; } else { printf("squashff: DecompressStoreFile completes second time?\n"); }; } else { printf("squashff: DecompressStoreFile completes first time?\n"); }; (void)_kernel_osfind(0, (char *)riscos_output); output = fopen(argv[1], "r"); /* Already written by above */ if (!output) { fprintf(stderr, "Cannot reopen '%s' for input\n", argv[1]); break; }; fseek(output, 0, SEEK_END); if (output_size != ftell(output)) { fprintf(stderr, "DecompressStoreFile produces incorrect output size, should be 0x%lx but was 0x%lx\n", output_size, ftell(output)); fclose(output); break; }; fseek(output, 0, SEEK_SET); if (fread(output_store_temp, 1, (size_t)output_size, output) != output_size) { fprintf(stderr, "Cannot read all of '%s' for input\n", argv[1]); fclose(output); break; }; fclose(output); if (memcmp(output_store, output_store_temp, (size_t)output_size)) { fprintf(stderr, "squashff: DecompressStoreFile comparison error\n"); break; }; }; printf("All tests ok\n"); bad = 0; break; }; }; if (bad) printf("squashff: %s\n", USAGE); return 0; }