📄 shorten.c
字号:
for(chan = 0; chan < nchan; chan++) { long coffset, *cbuffer = buffer[chan]; long sum, fnd; int resn; /* test for excessive and exploitable quantisation, and exploit!! */ { int newbitshift = find_bitshift(cbuffer, blocksize, ftype); if(newbitshift != bitshift) { uvar_put((ulong) FN_BITSHIFT, FNSIZE, fileo); uvar_put((ulong) newbitshift, BITSHIFTSIZE, fileo); bitshift = newbitshift; } } /* deduct mean if appropriate */ if(nmean == 0) coffset = default_offset; else { sum = 0; for(i = 0; i < nmean; i++) sum += offset[chan][i]; coffset = sum / nmean; sum = 0; for(i = 0; i < blocksize; i++) sum += cbuffer[i]; for(i = 1; i < nmean; i++) offset[chan][i - 1] = offset[chan][i]; offset[chan][nmean - 1] = sum / blocksize; } if(coffset != 0) for(i = -nwrap; i < blocksize; i++) cbuffer[i] -= coffset; /* find the best model */ if(maxnlpc == 0) { long sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0, last0, last1, last2; last2 = (last1 = (last0 = cbuffer[-1]) - cbuffer[-2]) - (cbuffer[-2] -cbuffer[-3]); for(i = 0; i < blocksize; i++) { long diff0, diff1, diff2, diff3; sum0 += abs(diff0 = cbuffer[i]); sum1 += abs(diff1 = diff0 - last0); sum2 += abs(diff2 = diff1 - last1); sum3 += abs(diff3 = diff2 - last2); last0 = diff0; last1 = diff1; last2 = diff2; } if(sum0 < MIN(MIN(sum1, sum2), sum3)) { sum = sum0; fnd = FN_DIFF0; } else if(sum1 < MIN(sum2, sum3)) { sum = sum1; fnd = FN_DIFF1; } else if(sum2 < sum3) { sum = sum2; fnd = FN_DIFF2; } else { sum = sum3; fnd = FN_DIFF3; } if(alpha * sum < blocksize) resn = 0; else resn = log(alpha * sum / (double) blocksize) / M_LN2 + 0.5; if(resn > maxresn) { bitshift = resn - maxresn; for(i = 0; i < blocksize; i++) cbuffer[i] >>= bitshift; resn = maxresn; } uvar_put(fnd, FNSIZE, fileo); uvar_put((ulong) resn, ENERGYSIZE, fileo); switch(fnd) { case FN_DIFF0: for(i = 0; i < blocksize; i++) VAR_PUT(cbuffer[i], resn, fileo); break; case FN_DIFF1: for(i = 0; i < blocksize; i++) VAR_PUT(cbuffer[i] - cbuffer[i - 1], resn, fileo); break; case FN_DIFF2: for(i = 0; i < blocksize; i++) VAR_PUT(cbuffer[i] - 2 * cbuffer[i - 1] + cbuffer[i - 2], resn, fileo); break; case FN_DIFF3: for(i = 0; i < blocksize; i++) VAR_PUT(cbuffer[i] - 3 * (cbuffer[i - 1] - cbuffer[i - 2]) - cbuffer[i - 3], resn, fileo); break; } } else { /* maxnlpc > 0 so do lpc analysis */ int nlpc = wav2lpc(cbuffer, blocksize, qlpc, maxnlpc, &resn); if(resn > maxresn) { bitshift = resn - maxresn; for(i = 0; i < blocksize; i++) cbuffer[i] >>= bitshift; resn = maxresn; } uvar_put((ulong) FN_QLPC, FNSIZE, fileo); uvar_put((ulong) resn, ENERGYSIZE, fileo); uvar_put((ulong) nlpc, LPCQSIZE, fileo); for(i = 0; i < nlpc; i++) var_put((long) qlpc[i], LPCQUANT, fileo); /* use the quantised LPC coefficients to generate the residual */ for(i = 0; i < blocksize; i++) { int j; long sum = 0; for(j = 0; j < nlpc; j++) sum += qlpc[j] * cbuffer[i - j - 1]; var_put(cbuffer[i] - (sum >> LPCQUANT), resn, fileo); } } /* do the wrap */ for(i = -nwrap; i < 0; i++) cbuffer[i] = cbuffer[i + blocksize] + coffset; } } /* wind up the variable frame rate file */ uvar_put((ulong) FN_QUIT, FNSIZE, fileo); var_put_quit(fileo); /* and free the space used */ free((char*) buffer); free((char*) buffer1); free((char*) offset); if(maxnlpc > 0) free((char*) qlpc); } else { /***********************/ /* EXTRACT starts here */ /***********************/ int i, cmd; /* read magic number */ for(i = 0; i < strlen(magic); i++) if(getc(filei) != magic[i]) usage_exit_s(1, "Bad magic number\n"); /* get and check version number */ if((version = getc(filei)) == EOF) update_exit_s(1, "EOF when reading version number\n"); if(version > FORMAT_VERSION) update_exit_sd(1, "can't decode version %d\n", version); /* initialise the variable length mode */ var_get_init(filei); /* get file type and set up appropriately, ignoring command line state */ ftype = UINT_GET(TYPESIZE, filei); nchan = UINT_GET(CHANSIZE, filei); /* get blocksize if version > 0 */ if(version > 0) { blocksize = UINT_GET((int) (log((double) DEFAULT_BLOCK_SIZE) / M_LN2), filei); maxnlpc = UINT_GET(LPCQSIZE, filei); nmean = UINT_GET(0, fileo); nskip = UINT_GET(NSKIPSIZE, filei); for(i = 0; i < nskip; i++) { int byte = uvar_get(XBYTESIZE, filei); if(putc(byte, fileo) == EOF) usage_exit_s(1, "EOF when writing header\n"); } } else blocksize = DEFAULT_BLOCK_SIZE; nwrap = MAX(NWRAP, maxnlpc); /* grab some space for the input buffer */ buffer = long2d((ulong) nchan, (ulong) (blocksize + nwrap)); offset = long2d((ulong) nchan, (ulong) nmean); for(chan = 0; chan < nchan; chan++) { for(i = 0; i < nwrap; i++) buffer[chan][i] = 0; buffer[chan] += nwrap; } if(maxnlpc > 0) qlpc = (int*) pmalloc((ulong) (maxnlpc * sizeof(*qlpc))); default_offset = init_offset(offset, nchan, nmean, ftype); /* get commands from file and execute them */ chan = 0; while((cmd = uvar_get(FNSIZE, filei)) != FN_QUIT) switch(cmd) { case FN_DIFF0: case FN_DIFF1: case FN_DIFF2: case FN_DIFF3: case FN_QLPC: { int resn = uvar_get(ENERGYSIZE, filei); long coffset, *cbuffer = buffer[chan]; int nlpc, j; /* this is a hack as version 0 differed in definition of var_get() */ if(version == 0) resn--; /* find offset */ if(nmean == 0) coffset = default_offset; else { long sum = 0; for(i = 0; i < nmean; i++) sum += offset[chan][i]; coffset = sum / nmean; } switch(cmd) { case FN_DIFF0: for(i = 0; i < blocksize; i++) cbuffer[i] = var_get(resn, filei) + coffset; break; case FN_DIFF1: for(i = 0; i < blocksize; i++) cbuffer[i] = var_get(resn, filei) + cbuffer[i - 1]; break; case FN_DIFF2: for(i = 0; i < blocksize; i++) cbuffer[i] = var_get(resn, filei) + (2 * cbuffer[i - 1] - cbuffer[i - 2]); break; case FN_DIFF3: for(i = 0; i < blocksize; i++) cbuffer[i] = var_get(resn, filei) + 3 * (cbuffer[i - 1] - cbuffer[i - 2]) + cbuffer[i - 3]; break; case FN_QLPC: nlpc = uvar_get(LPCQSIZE, filei); for(i = 0; i < nlpc; i++) qlpc[i] = var_get(LPCQUANT, filei); for(i = 0; i < nlpc; i++) cbuffer[i - nlpc] -= coffset; for(i = 0; i < blocksize; i++) { long sum = 0; for(j = 0; j < nlpc; j++) sum += qlpc[j] * cbuffer[i - j - 1]; cbuffer[i] = var_get(resn, filei) + (sum >> LPCQUANT); } if(coffset != 0) for(i = 0; i < blocksize; i++) cbuffer[i] += coffset; break; } /* store mean value if appropriate */ if(nmean > 0) { long sum = 0; for(i = 1; i < nmean; i++) offset[chan][i - 1] = offset[chan][i]; for(i = 0; i < blocksize; i++) sum += cbuffer[i]; offset[chan][nmean - 1] = sum / blocksize; } /* do the wrap */ for(i = -nwrap; i < 0; i++) cbuffer[i] = cbuffer[i + blocksize]; fix_bitshift(cbuffer, blocksize, bitshift, ftype); if(chan == nchan - 1) fwrite_type(buffer, ftype, nchan, blocksize, fileo); chan = (chan + 1) % nchan; } break; case FN_BLOCKSIZE: blocksize = UINT_GET((int) (log((double) blocksize) / M_LN2), filei); break; case FN_BITSHIFT: bitshift = uvar_get(BITSHIFTSIZE, filei); break; default: update_exit_sd(1, "sanity check fails trying to decode function: %d\n", cmd); } /* wind up */ var_get_quit(filei); free((char*) buffer); free((char*) offset); if(maxnlpc > 0) free((char*) qlpc); } #ifdef NOT_FOR_EMBEDDED_CODE /* close the files */ if(filei != stdi) fclose(filei); if(fileo != stdo) fclose(fileo); /* make the compressed file look like the original if possible */ if((filei != stdi) && (fileo != stdo)) (void) dupfileinfo(filenamei, filenameo); if(nfilename == 1) if(unlink(filenamei)) perror_exit_ss("unlink(%s)", filenamei);#endif if(tmpfilename != NULL) free(tmpfilename); /* quit happy */ return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -