Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <assert.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <zlib.h>
- #include <lz4.h>
- #include "lzf.h"
- #include <wavpack.h>
- #define FALSE 0
- #define TRUE 1
- static int write_block(void *id, void *data, int32_t length)
- {
- size_t w = fwrite(data, 1, length, id);
- return w == length ? TRUE : FALSE;
- }
- static int file_size_get(const char *filename)
- {
- struct stat d;
- int r;
- r = stat(filename, &d);
- if(r != 0){
- return -1;
- }
- return d.st_size;
- }
- static uint32_t packer_data_lz4(const uint8_t *src, int src_length, uint8_t *dest, int dest_length)
- {
- uint32_t r = LZ4_compress_default((const char *) src, (char *)dest, src_length, dest_length);
- return r >= src_length ? 0 : r;
- }
- static uint32_t packer_data_lzf(const uint8_t *src, int src_length, uint8_t *dest, int dest_length)
- {
- uint32_t r = lzf_compress(src, src_length, dest, src_length - 1);
- return r;
- }
- typedef uint32_t (*packer)(const uint8_t *src, int src_length, uint8_t *dest, int dest_length);
- #define COMPACTDISC_SECTOR_SIZE (2352)
- static int encode_main(FILE *const s, uint32_t src_sector_num, FILE *const d, packer packer, int lossy)
- {
- WavpackContext *w = WavpackOpenFileOutput(write_block, d, NULL);
- assert(w);
- WavpackConfig config;
- memset(&config, 0, sizeof(config));
- config.bytes_per_sample = 2;
- config.bits_per_sample = 16;
- config.channel_mask = 3;
- config.num_channels = 2;
- config.sample_rate = 44100;
- config.flags = CONFIG_JOINT_STEREO | CONFIG_VERY_HIGH_FLAG;
- if(lossy){
- config.flags |= CONFIG_HYBRID_FLAG | CONFIG_BITRATE_KBPS;
- config.bitrate = 196;
- }
- config.block_samples = COMPACTDISC_SECTOR_SIZE / config.bytes_per_sample / config.num_channels;
- int r = WavpackSetConfiguration64(w, &config, src_sector_num * config.block_samples, NULL);
- assert(r == TRUE);
- r = WavpackPackInit(w);
- assert(r == TRUE);
- const int bufnum = 0x100;
- int32_t *const sample_buffer = malloc(COMPACTDISC_SECTOR_SIZE * bufnum * sizeof(int32_t));
- uint8_t *const file_buffer = malloc(COMPACTDISC_SECTOR_SIZE * bufnum);
- int32_t *const audio_silent = calloc(config.block_samples * config.num_channels, sizeof(int32_t));
- const uint8_t compactdisc_data_header[] = {
- 0, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0
- };
- WavpackHeader h = {"wvpk", 0, 0x410, 0, 0, src_sector_num * config.block_samples, 0, 0, 0x14801821, 0};
- assert(sizeof(h) == 0x20);
- while(src_sector_num){
- const uint32_t l = src_sector_num < bufnum ? src_sector_num : bufnum;
- fread(file_buffer, 1, l * COMPACTDISC_SECTOR_SIZE, s);
- int32_t *b = sample_buffer;
- for(uint32_t i = 0; i < l * COMPACTDISC_SECTOR_SIZE; i += 2, b++){
- *b = (file_buffer[i] & 0xff);
- *b |= (file_buffer[i + 1] & 0xff)<< 8;
- }
- #if 0
- r = WavpackPackSamples(w, sample_buffer, l * config.block_samples);
- assert(r == TRUE);
- #else
- b = sample_buffer;
- const uint8_t *fb = file_buffer;
- for(uint32_t i = 0; i < l; i++, b += config.block_samples * config.num_channels, fb += COMPACTDISC_SECTOR_SIZE){
- int32_t *audio_src = b;
- if(memcmp(compactdisc_data_header, fb, sizeof(compactdisc_data_header)) == 0){
- uint8_t compressed_data[0x800];
- uint32_t compressed_size = (*packer)(fb + 0x10, 0x800, compressed_data, 0x800);
- if(compressed_size == 0){
- compressed_size = 0x800;
- memcpy(compressed_data, fb+10, 0x800);
- }
- h.ckSize = 0x20 - 8 + compressed_size;
- h.crc = crc32(0, fb + 0x10, 0x800);
- fwrite(&h, 1, 0x20, d);
- fwrite(compressed_data, 1, compressed_size, d);
- audio_src = audio_silent;
- }
- r = WavpackPackSamples(w, audio_src, config.block_samples);
- assert(r == TRUE);
- r = WavpackFlushSamples(w);
- assert(r == TRUE);
- h.block_index += config.block_samples;
- }
- #endif
- src_sector_num -= l;
- }
- free(sample_buffer);
- free(file_buffer);
- free(audio_silent);
- r = WavpackFlushSamples(w);
- assert(r == TRUE);
- WavpackCloseFile(w);
- return 0;
- }
- int main(int c, const char **v)
- {
- if(c < 4){
- puts("e [lz4|lzf|lz4y|lzfy] [src.img] [dest.wv]");
- return 1;
- }
- int src_file_size = file_size_get(v[2]);
- if((src_file_size % COMPACTDISC_SECTOR_SIZE) != 0){
- printf("filesize_error, %s %% 2352 != 0\n", v[1]);
- return 1;
- }
- packer packer = NULL;
- int lossy = 0;
- if(strncmp(v[1], "lz4", 5) == 0){
- packer = packer_data_lz4;
- }else if(strncmp(v[1], "lz4y", 5) == 0){
- packer = packer_data_lz4;
- lossy = 1;
- }else if(strncmp(v[1], "lzf", 5) == 0){
- packer = packer_data_lzf;
- }else if(strncmp(v[1], "lzfy", 5) == 0){
- packer = packer_data_lzf;
- lossy = 1;
- }else{
- puts("e [lz4|lzf|lz4y|lzfy] [src.img] [dest.wv]");
- return 1;
- }
- FILE *const s = fopen(v[2], "rb");
- FILE *d = fopen(v[3], "wb");
- int r = encode_main(s, src_file_size / COMPACTDISC_SECTOR_SIZE, d, packer, lossy);
- fclose(d);
- fclose(s);
- return r;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement