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;
}
Example #2
0
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;
}