mirror of
https://github.com/schnaader/precomp-cpp
synced 2026-08-23 00:23:04 -04:00
Recompress MP3 files up to 64 MB in memory
- Added helper functions to copy data, file<->memory - Related: Issue #14
This commit is contained in:
parent
c8dc5a0980
commit
a75eb06711
2 changed files with 108 additions and 35 deletions
|
|
@ -1,8 +1,14 @@
|
|||
#include "../packjpg/bitops.h" // for MBITS
|
||||
#include "pmp3tbl.h"
|
||||
|
||||
// function to convert MP3 to PMP and vice versa
|
||||
#define MP3_MAX_MEMORY_SIZE 64 * 1024 * 1024
|
||||
|
||||
// function to convert MP3 to PMP and vice versa, file to file
|
||||
bool pmplib_convert_file2file( char* in, char* out, char* msg );
|
||||
|
||||
// functions to convert MP3 to PMP and vice versa, in memory
|
||||
void pmplib_init_streams( void* in_src, int in_type, int in_size, void* out_dest, int out_type );
|
||||
bool pmplib_convert_stream2mem( unsigned char** out_file, unsigned int* out_size, char* msg );
|
||||
|
||||
// this function writes versioninfo for the packMP3 DLL to a string
|
||||
const char* pmplib_version_info( void );
|
||||
|
|
|
|||
135
precomp.cpp
135
precomp.cpp
|
|
@ -5829,7 +5829,42 @@ void fast_copy(FILE* file1, FILE* file2, long long bytecount) {
|
|||
own_fread(copybuf, 1, remaining_bytes, file1);
|
||||
own_fwrite(copybuf, 1, remaining_bytes, file2);
|
||||
}
|
||||
}
|
||||
|
||||
void fast_copy_file_to_mem(FILE* file, unsigned char* mem, long long bytecount) {
|
||||
if (bytecount == 0) return;
|
||||
|
||||
long long i;
|
||||
int remaining_bytes = (bytecount % COPY_BUF_SIZE);
|
||||
long long maxi = (bytecount / COPY_BUF_SIZE);
|
||||
|
||||
for (i = 1; i <= maxi; i++) {
|
||||
own_fread(mem + (i - 1) * COPY_BUF_SIZE, 1, COPY_BUF_SIZE, file);
|
||||
|
||||
if (((i - 1) % FAST_COPY_WORK_SIGN_DIST) == 0)
|
||||
print_work_sign(true);
|
||||
}
|
||||
if (remaining_bytes != 0) {
|
||||
own_fread(mem + maxi * COPY_BUF_SIZE, 1, remaining_bytes, file);
|
||||
}
|
||||
}
|
||||
|
||||
void fast_copy_mem_to_file(unsigned char* mem, FILE* file, long long bytecount) {
|
||||
if (bytecount == 0) return;
|
||||
|
||||
long long i;
|
||||
int remaining_bytes = (bytecount % COPY_BUF_SIZE);
|
||||
long long maxi = (bytecount / COPY_BUF_SIZE);
|
||||
|
||||
for (i = 1; i <= maxi; i++) {
|
||||
own_fwrite(mem + (i - 1) * COPY_BUF_SIZE, 1, COPY_BUF_SIZE, file);
|
||||
|
||||
if (((i - 1) % FAST_COPY_WORK_SIGN_DIST) == 0)
|
||||
print_work_sign(true);
|
||||
}
|
||||
if (remaining_bytes != 0) {
|
||||
own_fwrite(mem + maxi * COPY_BUF_SIZE, 1, remaining_bytes, file);
|
||||
}
|
||||
}
|
||||
|
||||
size_t own_fwrite(const void *ptr, size_t size, size_t count, FILE* stream, int final_byte) {
|
||||
|
|
@ -7258,31 +7293,48 @@ void try_decompression_mp3 (long long mp3_length) {
|
|||
}
|
||||
|
||||
bool mp3_success = false;
|
||||
|
||||
// try to decompress at current position
|
||||
fmp3 = tryOpen(tempfile0,"wb");
|
||||
seek_64(fin, input_file_pos);
|
||||
fast_copy(fin, fmp3, mp3_length);
|
||||
safe_fclose(&fmp3);
|
||||
remove(tempfile1);
|
||||
|
||||
// workaround for bugs, similar to packJPG
|
||||
FILE* fworkaround = tryOpen(tempfile1,"wb");
|
||||
safe_fclose(&fworkaround);
|
||||
|
||||
bool recompress_success = false;
|
||||
{
|
||||
char msg[256];
|
||||
recompress_success = pmplib_convert_file2file(tempfile0, tempfile1, msg);
|
||||
char recompress_msg[256];
|
||||
unsigned char* mp3_mem_in = NULL;
|
||||
unsigned char* mp3_mem_out = NULL;
|
||||
unsigned int mp3_mem_out_size = -1;
|
||||
bool in_memory = (mp3_length <= MP3_MAX_MEMORY_SIZE);
|
||||
|
||||
if ((!recompress_success) && (strncmp(msg, "synching failure", 16) == 0)) {
|
||||
int frame_n;
|
||||
int pos;
|
||||
if (sscanf(msg, "synching failure (frame #%i at 0x%X)", &frame_n, &pos) == 2) {
|
||||
if ((pos > 0) && (pos < mp3_length)) {
|
||||
mp3_length = pos;
|
||||
if (in_memory) { // small stream => do everything in memory
|
||||
mp3_mem_in = new unsigned char[mp3_length];
|
||||
seek_64(fin, input_file_pos);
|
||||
fast_copy_file_to_mem(fin, mp3_mem_in, mp3_length);
|
||||
|
||||
pmplib_init_streams(mp3_mem_in, 1, mp3_length, mp3_mem_out, 1);
|
||||
recompress_success = pmplib_convert_stream2mem(&mp3_mem_out, &mp3_mem_out_size, recompress_msg);
|
||||
} else { // large stream => use temporary files
|
||||
// try to decompress at current position
|
||||
fmp3 = tryOpen(tempfile0,"wb");
|
||||
seek_64(fin, input_file_pos);
|
||||
fast_copy(fin, fmp3, mp3_length);
|
||||
safe_fclose(&fmp3);
|
||||
remove(tempfile1);
|
||||
|
||||
if (DEBUG_MODE) printf ("Too much garbage data at the end, retry with new length %i\n", pos);
|
||||
// workaround for bugs, similar to packJPG
|
||||
FILE* fworkaround = tryOpen(tempfile1,"wb");
|
||||
safe_fclose(&fworkaround);
|
||||
|
||||
recompress_success = pmplib_convert_file2file(tempfile0, tempfile1, recompress_msg);
|
||||
}
|
||||
|
||||
if ((!recompress_success) && (strncmp(recompress_msg, "synching failure", 16) == 0)) {
|
||||
int frame_n;
|
||||
int pos;
|
||||
if (sscanf(recompress_msg, "synching failure (frame #%i at 0x%X)", &frame_n, &pos) == 2) {
|
||||
if ((pos > 0) && (pos < mp3_length)) {
|
||||
mp3_length = pos;
|
||||
|
||||
if (DEBUG_MODE) printf ("Too much garbage data at the end, retry with new length %i\n", pos);
|
||||
|
||||
if (in_memory) {
|
||||
pmplib_init_streams(mp3_mem_in, 1, mp3_length, mp3_mem_out, 1);
|
||||
recompress_success = pmplib_convert_stream2mem(&mp3_mem_out, &mp3_mem_out_size, recompress_msg);
|
||||
} else {
|
||||
fmp3 = tryOpen(tempfile0, "r+b");
|
||||
ftruncate(fileno(fmp3), pos);
|
||||
safe_fclose(&fmp3);
|
||||
|
|
@ -7291,27 +7343,36 @@ void try_decompression_mp3 (long long mp3_length) {
|
|||
// workaround for bugs, similar to packJPG
|
||||
FILE* fworkaround = tryOpen(tempfile1,"wb");
|
||||
safe_fclose(&fworkaround);
|
||||
|
||||
recompress_success = pmplib_convert_file2file(tempfile0, tempfile1, msg);
|
||||
|
||||
recompress_success = pmplib_convert_file2file(tempfile0, tempfile1, recompress_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decompressed_streams_count++;
|
||||
decompressed_mp3_count++;
|
||||
decompressed_streams_count++;
|
||||
decompressed_mp3_count++;
|
||||
|
||||
if (!recompress_success) {
|
||||
if (DEBUG_MODE) printf ("packMP3 error: %s\n", msg);
|
||||
}
|
||||
if (!recompress_success) {
|
||||
if (DEBUG_MODE) printf ("packMP3 error: %s\n", recompress_msg);
|
||||
}
|
||||
|
||||
if (!in_memory) {
|
||||
remove(tempfile0);
|
||||
}
|
||||
|
||||
if (recompress_success) {
|
||||
ftempout = tryOpen(tempfile1,"rb");
|
||||
fseek(ftempout, 0, SEEK_END);
|
||||
int mp3_new_length = ftell(ftempout);
|
||||
safe_fclose(&ftempout);
|
||||
int mp3_new_length = -1;
|
||||
|
||||
if (in_memory) {
|
||||
mp3_new_length = mp3_mem_out_size;
|
||||
} else {
|
||||
ftempout = tryOpen(tempfile1,"rb");
|
||||
fseek(ftempout, 0, SEEK_END);
|
||||
mp3_new_length = ftell(ftempout);
|
||||
safe_fclose(&ftempout);
|
||||
}
|
||||
|
||||
if (mp3_new_length > 0) {
|
||||
recompressed_streams_count++;
|
||||
recompressed_mp3_count++;
|
||||
|
|
@ -7343,7 +7404,11 @@ void try_decompression_mp3 (long long mp3_length) {
|
|||
fout_fput32(best_identical_bytes_decomp);
|
||||
|
||||
// write compressed MP3
|
||||
write_decompressed_data(best_identical_bytes_decomp);
|
||||
if (in_memory) {
|
||||
fast_copy_mem_to_file(mp3_mem_out, fout, best_identical_bytes_decomp);
|
||||
} else {
|
||||
write_decompressed_data(best_identical_bytes_decomp);
|
||||
}
|
||||
|
||||
// start new uncompressed data
|
||||
|
||||
|
|
@ -7357,6 +7422,8 @@ void try_decompression_mp3 (long long mp3_length) {
|
|||
}
|
||||
}
|
||||
|
||||
if (mp3_mem_in != NULL) delete[] mp3_mem_in;
|
||||
if (mp3_mem_out != NULL) delete[] mp3_mem_out;
|
||||
}
|
||||
|
||||
void try_decompression_zlib(int windowbits) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue