Advertisement
Guest User

Untitled

a guest
Feb 11th, 2021
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.84 KB | None | 0 0
  1. #include <assert.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <sys/stat.h>
  7. #include <zlib.h>
  8. #include <lz4.h>
  9. #include "lzf.h"
  10. #include <wavpack.h>
  11. #define FALSE 0
  12. #define TRUE 1
  13.  
  14. static int write_block(void *id, void *data, int32_t length)
  15. {
  16.     size_t w = fwrite(data, 1, length, id);
  17.     return w == length ? TRUE : FALSE;
  18. }
  19. static int file_size_get(const char *filename)
  20. {
  21.     struct stat d;
  22.     int r;
  23.     r = stat(filename, &d);
  24.     if(r != 0){
  25.         return -1;
  26.     }
  27.     return d.st_size;
  28. }
  29. static uint32_t packer_data_lz4(const uint8_t *src, int src_length, uint8_t *dest, int dest_length)
  30. {
  31.     uint32_t r = LZ4_compress_default((const char *) src, (char *)dest, src_length, dest_length);
  32.     return r >= src_length ? 0 : r;
  33. }
  34. static uint32_t packer_data_lzf(const uint8_t *src, int src_length, uint8_t *dest, int dest_length)
  35. {
  36.     uint32_t r = lzf_compress(src, src_length, dest, src_length - 1);
  37.     return r;
  38. }
  39. typedef uint32_t (*packer)(const uint8_t *src, int src_length, uint8_t *dest, int dest_length);
  40. #define COMPACTDISC_SECTOR_SIZE (2352)
  41. static int encode_main(FILE *const s, uint32_t src_sector_num, FILE *const d, packer packer, int lossy)
  42. {
  43.     WavpackContext *w = WavpackOpenFileOutput(write_block, d, NULL);
  44.     assert(w);
  45.  
  46.     WavpackConfig config;
  47.     memset(&config, 0, sizeof(config));
  48.     config.bytes_per_sample = 2;
  49.     config.bits_per_sample = 16;
  50.     config.channel_mask = 3;
  51.     config.num_channels = 2;
  52.     config.sample_rate = 44100;
  53.     config.flags = CONFIG_JOINT_STEREO | CONFIG_VERY_HIGH_FLAG;
  54.     if(lossy){
  55.         config.flags |= CONFIG_HYBRID_FLAG | CONFIG_BITRATE_KBPS;
  56.         config.bitrate = 196;
  57.     }
  58.     config.block_samples = COMPACTDISC_SECTOR_SIZE / config.bytes_per_sample / config.num_channels;
  59.     int r = WavpackSetConfiguration64(w, &config, src_sector_num * config.block_samples, NULL);
  60.     assert(r == TRUE);
  61.     r = WavpackPackInit(w);
  62.     assert(r == TRUE);
  63.    
  64.     const int bufnum = 0x100;
  65.     int32_t *const sample_buffer = malloc(COMPACTDISC_SECTOR_SIZE * bufnum * sizeof(int32_t));
  66.     uint8_t *const file_buffer = malloc(COMPACTDISC_SECTOR_SIZE * bufnum);
  67.     int32_t *const audio_silent = calloc(config.block_samples * config.num_channels, sizeof(int32_t));
  68.     const uint8_t compactdisc_data_header[] = {
  69.         0, 0xff, 0xff, 0xff, 0xff, 0xff,
  70.         0xff, 0xff, 0xff, 0xff, 0xff, 0
  71.     };
  72.     WavpackHeader h = {"wvpk", 0, 0x410, 0, 0, src_sector_num * config.block_samples, 0, 0, 0x14801821, 0};
  73.     assert(sizeof(h) == 0x20);
  74.     while(src_sector_num){
  75.         const uint32_t l = src_sector_num < bufnum ? src_sector_num : bufnum;
  76.         fread(file_buffer, 1, l * COMPACTDISC_SECTOR_SIZE, s);
  77.         int32_t *b = sample_buffer;
  78.         for(uint32_t i = 0; i < l * COMPACTDISC_SECTOR_SIZE; i += 2, b++){
  79.             *b = (file_buffer[i] & 0xff);
  80.             *b |= (file_buffer[i + 1] & 0xff)<< 8;
  81.         }
  82. #if 0
  83.         r = WavpackPackSamples(w, sample_buffer, l * config.block_samples);
  84.         assert(r == TRUE);
  85. #else
  86.         b = sample_buffer;
  87.         const uint8_t *fb = file_buffer;
  88.         for(uint32_t i = 0; i < l; i++, b += config.block_samples * config.num_channels, fb += COMPACTDISC_SECTOR_SIZE){
  89.             int32_t *audio_src = b;
  90.             if(memcmp(compactdisc_data_header, fb, sizeof(compactdisc_data_header)) == 0){
  91.                 uint8_t compressed_data[0x800];
  92.                 uint32_t compressed_size = (*packer)(fb + 0x10, 0x800, compressed_data, 0x800);
  93.                 if(compressed_size == 0){
  94.                     compressed_size = 0x800;
  95.                     memcpy(compressed_data, fb+10, 0x800);
  96.                 }
  97.                 h.ckSize = 0x20 - 8 + compressed_size;
  98.                 h.crc = crc32(0, fb + 0x10, 0x800);
  99.                 fwrite(&h, 1, 0x20, d);
  100.                 fwrite(compressed_data, 1, compressed_size, d);
  101.  
  102.                 audio_src = audio_silent;
  103.             }
  104.             r = WavpackPackSamples(w, audio_src, config.block_samples);
  105.             assert(r == TRUE);
  106.             r = WavpackFlushSamples(w);
  107.             assert(r == TRUE);
  108.             h.block_index += config.block_samples;
  109.         }
  110. #endif
  111.         src_sector_num -= l;
  112.     }
  113.     free(sample_buffer);
  114.     free(file_buffer);
  115.     free(audio_silent);
  116.    
  117.     r = WavpackFlushSamples(w);
  118.     assert(r == TRUE);
  119.     WavpackCloseFile(w);
  120.     return 0;
  121. }
  122.  
  123. int main(int c, const char **v)
  124. {
  125.     if(c < 4){
  126.         puts("e [lz4|lzf|lz4y|lzfy] [src.img] [dest.wv]");
  127.         return 1;
  128.     }
  129.     int src_file_size = file_size_get(v[2]);
  130.     if((src_file_size % COMPACTDISC_SECTOR_SIZE) != 0){
  131.         printf("filesize_error, %s %% 2352 != 0\n", v[1]);
  132.         return 1;
  133.     }
  134.     packer packer = NULL;
  135.     int lossy = 0;
  136.     if(strncmp(v[1], "lz4", 5) == 0){
  137.         packer = packer_data_lz4;
  138.     }else if(strncmp(v[1], "lz4y", 5) == 0){
  139.         packer = packer_data_lz4;
  140.         lossy = 1;
  141.     }else if(strncmp(v[1], "lzf", 5) == 0){
  142.         packer = packer_data_lzf;
  143.     }else if(strncmp(v[1], "lzfy", 5) == 0){
  144.         packer = packer_data_lzf;
  145.         lossy = 1;
  146.     }else{
  147.         puts("e [lz4|lzf|lz4y|lzfy] [src.img] [dest.wv]");
  148.         return 1;
  149.     }
  150.     FILE *const s = fopen(v[2], "rb");
  151.     FILE *d = fopen(v[3], "wb");
  152.     int r = encode_main(s, src_file_size / COMPACTDISC_SECTOR_SIZE, d, packer, lossy);
  153.     fclose(d);
  154.     fclose(s);
  155.     return r;
  156. }
  157.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement