unsigned int decomp_pp20(Bit8u *dst, Bit8u *src, unsigned int plen) { size_t unplen; if (plen < 4) D2_ERR("PP20: Length argument is below 4\n"); unplen = depackedlen(src, plen); if (unplen == 0) { D2_ERR("PP20: No PP20 file\n"); } ppDecrunch(&src[8], dst, &src[4], plen - 12, unplen, src[plen -1]); return unplen; }
static int ppdepack(uint8 *data, size_t len, FILE *fo) { /* PP FORMAT: * 1 longword identifier 'PP20' or 'PX20' * [1 word checksum (if 'PX20') $ssss] * 1 longword efficiency $eeeeeeee * X longwords crunched file $cccccccc,$cccccccc,... * 1 longword decrunch info 'decrlen' << 8 | '8 bits other info' */ int success=0; uint8 *output /*, crypted*/; uint32 outlen; if (len < 16) { /*fprintf(stderr, "File is too short to be a PP file (%u bytes)\n", len);*/ return -1; } if (data[0]=='P' && data[1]=='P' && data[2]=='2' && data[3]=='0') { if (len & 0x03) { /*fprintf(stderr, "File length is not a multiple of 4\n");*/ return -1; } /*crypted = 0;*/ } #if 0 else if (data[0]=='P' && data[1]=='X' && data[2]=='2' && data[3]=='0') { if ((len-2) & 0x03) { /*fprintf(stderr, "(file length - 2) is not a multiple of 4\n");*/ return -1; } crypted = 1; } #endif else { /*fprintf(stderr, "File does not have the PP signature\n");*/ return -1; } outlen = (data[len-4]<<16) | (data[len-3]<<8) | data[len-2]; /* fprintf(stderr, "decrunched length = %u bytes\n", outlen); */ output = (uint8 *) malloc(outlen); if (output == NULL) { /*fprintf(stderr, "out of memory!\n");*/ return -1; } /* if (crypted == 0) { */ /*fprintf(stderr, "not encrypted, decrunching anyway\n"); */ if (ppDecrunch(&data[8], output, &data[4], len-12, outlen, data[len-1])) { /* fprintf(stderr, "Decrunch successful! "); */ savefile(fo, (void *) output, outlen); } else { success=-1; } /*} else { success=-1; }*/ free(output); return success; }