Пример #1
0
Файл: pb.c Проект: boateam/boa
void decode_protobuf(char *buf, char *buf_end, yield_t yield)
{
    while(buf < buf_end)
    {
        uint64_t key = decode_varint(buf, &buf);
        struct key_value_pair pair = {
            .field_number = key >> 3,
            .wire_type = key & 0x07
        };
        switch(pair.wire_type)
        {
            case WT_VARINT:  /* varint */
                pair.value.varint = decode_varint(buf, &buf);
                break;

            case WT_64BIT:  /* 64 bit */
                pair.value._64_bit = get_32_le(buf, &buf);
                buf += 4;
                pair.value._64_bit |= (uint64_t)get_32_le(buf, &buf) << 32;
                buf += 4;
                break;

            case WT_STRING:  /* string */
                pair.value.string.len = decode_varint(buf, &buf);
                pair.value.string.start = buf;
                buf += pair.value.string.len;
                break;

            case WT_32BIT:  /* 32 bit */
                pair.value._32_bit = get_32_le(buf, &buf);
                buf += 4;
                break;
        }

        yield(&pair);
    }
}

void yield_cb(struct key_value_pair *pair)
{
    printf("Field number: %d, Wire type: %d\n", pair->field_number,
                                                pair->wire_type);
}
Пример #2
0
int main(int argc, char **argv)
{

    /* input file name */
    const char *infile_name = NULL;
    CHECK_ERROR(argc != 2, "needs one argument: file to work on");
    infile_name = argv[1];

    /* input file */
    FILE *infile = fopen(infile_name, "rb");
    CHECK_ERRNO(NULL == infile, "input file open failed");

    CHECK_ERROR(get_32_le(infile) != 3 || get_32_le(infile) != 0 || get_32_le(infile) != 3 || get_32_le(infile) != 1 || get_32_le(infile) != 0,"whither 30310?!?");

    const uint32_t data_size = get_32_le(infile);
    printf("data size   = 0x08%" PRIx32 "\n", data_size);

    const uint32_t header_size = get_32_le(infile);
    printf("header size = 0x%08" PRIx32 "\n", header_size);

    process_dir_list(0x1C, header_size, data_size, infile);
}
Пример #3
0
int main(int argc, char ** argv)
{
    if (argc != 3)
    {
        fprintf(stderr, "usage: %s infile.WwiseBank outfile_prefix\n", argv[0]);
        return 1;
    }

    FILE *infile = fopen(argv[1], "rb");

    CHECK_ERRNO(!infile, "failed opening input");

    const char * outfile_prefix = argv[2];

    CHECK_ERROR(UINT32_C(-1) != get_32_be(infile), "missing magic -1");


    long DATA_offset = -1;
    uint32_t DATA_size = 0;

    {
        int done = 0;
        long chunk_start = 0x80;

        // top level wwise chunks loop
        while (!done)
        {
            CHECK_ERRNO(-1 == fseek(infile, chunk_start, SEEK_SET), "fseek to BKHD chunk failed");

            const uint32_t chunk_id = get_32_be(infile);
            const uint32_t chunk_size = get_32_be(infile);

            switch (chunk_id)
            {
                case UINT32_C(0x424B4844):  // BKHD: Bank Header?
                case UINT32_C(0x44494458):  // DIDX: Data Index?
                case UINT32_C(0x48495243):  // HIRC
                case UINT32_C(0x53544944):  // STID: Stream Identifier?
                    break;
                case UINT32_C(0):
                    // 16 bytes padding at end, starting with 0s
                    done = 1;
                    break;
                case UINT32_C(0x44415441):  // DATA: body
                    DATA_offset = chunk_start + 8;
                    DATA_size = chunk_size;
                    break;
                default:
                    CHECK_ERROR(1, "unknown chunk id");
                    break;
            }

            chunk_start += 8 + chunk_size;
        }

        CHECK_ERROR(DATA_offset == -1, "no DATA chunk found in BKHD");
    }

    {
        int file_idx = 0;

        long subfile_offset = DATA_offset;

        // subfile loop
        while (subfile_offset < DATA_offset + DATA_size)
        {
            CHECK_ERRNO(-1 == fseek(infile, subfile_offset, SEEK_SET), "fseek to subfile failed");

            const uint32_t subfile_id = get_32_be(infile);
            const uint32_t subfile_size = get_32_le(infile);    // SAY WHAT?!?
            switch (subfile_id)
            {
                case UINT32_C(0x52494658):  // RIFX
                    break;
                default:
                    CHECK_ERROR(1, "unexpected subfile type");
                    break;
            }

            handle_RIFX(subfile_size, infile, outfile_prefix, file_idx);
            subfile_offset += subfile_size;
            file_idx ++;
        }
    }

    return 0;
}
Пример #4
0
uint32_t get_32_le_seek(long offset, FILE *infile)
{
    CHECK_ERRNO(fseek(infile, offset, SEEK_SET) != 0, "fseek");

    return get_32_le(infile);
}
Пример #5
0
int main(int argc, char **argv)
{
    const char *infile_name = NULL;
    const char *outfile_name = NULL;
    if (argc != 3) {
        fprintf(stderr, "build GENH from Taiko no Tatsukin Atsumete Tomodachi Daisakusen .nus3bank\n");
        fprintf(stderr, "usage: ttatd SONG_YUGEN.nus3bank SONG_YUGEN.genh\n");
        return -1;
    }

    infile_name = argv[1];
    outfile_name = argv[2];

    FILE *infile = fopen(infile_name, "rb");
    CHECK_ERRNO(NULL == infile, "input file open failed");

    const long nus3_offset = 0;
    EXPECT_32_BE(nus3_offset, infile, 0x4E555333, "NUS3");
    const long nus3_size = get_32_le_seek(nus3_offset + 4, infile) + 8;
    const long nus3_end = nus3_offset + nus3_size;

    EXPECT_32_BE(nus3_offset + 8, infile, 0x42414E4B, "BANK");

    long chunk_offset = nus3_offset + 12;

    long PACK_offset = -1;
    uint32_t PACK_size = 0;

    /* scan to find PACK */
    while (chunk_offset < nus3_end)
    {
        uint32_t chunk_type = get_32_be_seek(chunk_offset, infile);
        long     chunk_size = get_32_le(infile);

        //printf("offset: %"PRIx32" type: %"PRIx32" size: %"PRIx32"\n", (uint32_t)chunk_offset, chunk_type, (uint32_t)chunk_size);

        switch (chunk_type)
        {
            case UINT32_C(0x544F4320):  /* TOC  */
            case UINT32_C(0x50524F50):  /* PROP */
            case UINT32_C(0x42494E46):  /* BINF */
            case UINT32_C(0x47525020):  /* GRP  */
            case UINT32_C(0x44544F4E):  /* DTON */
            case UINT32_C(0x544F4E45):  /* TONE */
            case UINT32_C(0x4A554E4B):  /* JUNK */
                break;

            case UINT32_C(0x5041434B):  /* PACK */
                CHECK_ERROR(PACK_offset != -1, "expected only one PACK");
                PACK_offset = chunk_offset + 8;
                PACK_size = chunk_size;
                break;

            default:
                fprintf(stderr, "unexpected chunk %"PRIx32" at 0x%lx\n", chunk_type, chunk_offset);
                CHECK_ERROR(1, "who knows?");
                break;
        }
        chunk_offset += 8 + chunk_size;
        CHECK_ERROR(chunk_offset > nus3_end, "truncated chunk");
    }

    CHECK_ERROR(PACK_offset == -1, "missing PACK");

    const long IDSP_offset = PACK_offset;
    EXPECT_32_BE(IDSP_offset, infile, 0x49445350, "IDSP");

    EXPECT_32_BE(IDSP_offset + 4, infile, 0, "0 at IDSP+4");
    const uint32_t channels    = get_32_be_seek(IDSP_offset + 0x08, infile);
    CHECK_ERROR(channels != 1 && channels != 2,
        "only mono and stereo supported in GENH");

    const uint32_t sample_rate = get_32_be_seek(IDSP_offset + 0x0c, infile);
    const uint32_t sample_count= get_32_be_seek(IDSP_offset + 0x10, infile);
    EXPECT_32_BE(IDSP_offset + 0x14, infile, 0, "0 at IDSP+0x14");
    EXPECT_32_BE(IDSP_offset + 0x18, infile, 0, "0 at IDSP+0x18");
    EXPECT_32_BE(IDSP_offset + 0x1c, infile, 0, "0 at IDSP+0x1c");
    const uint32_t ch_head_offset = get_32_be_seek(IDSP_offset + 0x20, infile);
    const uint32_t ch_head_size   = get_32_be_seek(IDSP_offset + 0x24, infile);
    const uint32_t ch_body_offset = get_32_be_seek(IDSP_offset + 0x28, infile);
    const uint32_t ch_body_size   = get_32_be_seek(IDSP_offset + 0x2c, infile);

    CHECK_ERROR(ch_head_size != 0x60, "expected 0x60 header per channel");

    int loop_flag = 0;
    int loop_start = 0;
    int loop_end = 0;

    /* read header for checking and loop info */
    for (unsigned int c = 0; c < channels; c++) {
        struct dsp_header h;
        read_dsp_header(&h, infile, IDSP_offset + ch_head_offset + ch_head_size * c);

        CHECK_ERROR(h.sample_count != sample_count, "sample count mismatch");
        CHECK_ERROR(dsp_nibbles_to_samples(h.nibble_count) != sample_count, "nibble count mismatch");
        CHECK_ERROR(h.sample_rate  != sample_rate,  "sample rate mismatch");
        CHECK_ERROR(h.format != 0, "not DSP format?");

        CHECK_ERROR(c > 0 && ((h.loop_flag && !loop_flag) || (!h.loop_flag && loop_flag)), "loop flag mismatch");

        if (h.loop_flag) {
            loop_flag = 1;
            uint32_t new_loop_start = dsp_nibbles_to_samples(h.loop_start_offset);
            uint32_t new_loop_end   = dsp_nibbles_to_samples(h.loop_end_offset);
            if (c > 0) {
                CHECK_ERROR(loop_start != new_loop_start || loop_end != new_loop_end, "loop point mismatch");
            }

            loop_start = new_loop_start;
            loop_end = new_loop_end;
        }
    }


    long IDSP_size = ch_head_offset + (ch_head_size + ch_body_size) * channels;
    CHECK_ERROR(IDSP_size != PACK_size, "IDSP size does not match PACK size");

    /* build GENH */
    unsigned char genh_head[0x38];
    memset(genh_head, 0, sizeof(genh_head));

    /* header magic */
    memcpy(&genh_head[0x00], "GENH", 4);

    /* channel count */
    write_32_le(channels, &genh_head[0x04]);

    /* interleave */
    if (channels == 1)
    {
      write_32_le(0, &genh_head[0x08]);
    }
    else if (channels == 2)
    {
      // no interleave, but GENH does split data like this
      write_32_le(ch_body_size, &genh_head[0x08]);
    }

    /* sample rate */
    write_32_le(sample_rate, &genh_head[0x0c]);

    /* loop start */
    if (loop_flag) {
        write_32_le(loop_start, &genh_head[0x10]);
    } else {
        write_32_le(~UINT32_C(0), &genh_head[0x10]);
    }

    /* loop end */
    if (loop_flag) {
        write_32_le(loop_end, &genh_head[0x14]);
    } else {
        write_32_le(sample_count, &genh_head[0x14]);
    }

    /* coding type, coding_NGC_DSP */
    write_32_le(12, &genh_head[0x18]);

    /* start_offset */
    write_32_le(0x38 + IDSP_offset + ch_body_offset, &genh_head[0x1c]);

    /* header_size */
    write_32_le(0x38, &genh_head[0x20]);

    /* dsp coefs */
    write_32_le(0x38 + IDSP_offset + ch_head_offset + 0x1c, &genh_head[0x24]);
    if (channels == 2) {
        write_32_le(0x38 + IDSP_offset + ch_head_offset + ch_head_size + 0x1c, &genh_head[0x28]);
    }

    /* dsp interleave type */
    if (channels == 1) {
        /* no interleave */
          write_32_le(2, &genh_head[0x2c]);
    }

    /* normal coefs */
    //write_32_le(0, &genh_head[0x30]);

    FILE *outfile = fopen(outfile_name, "wb");
    CHECK_ERRNO(NULL == outfile, "output file open failed");

    put_bytes(outfile, genh_head, sizeof(genh_head));
    dump(infile, outfile, nus3_offset, nus3_size);

    CHECK_ERRNO(EOF == fclose(outfile), "fclose of output file");
}
Пример #6
0
void analyze_Huf8(FILE *infile, FILE *outfile, long file_length)
{
    unsigned char *decode_table = NULL;
    int decode_table_size;
    long decoded_length;
    int symbol_count;

    /* read header */
    {
        unsigned char buf[5];
        get_bytes_seek(0, infile, buf, 5);
        CHECK_ERROR (buf[0] != 0x28, "not 8-bit Huffman");
        decoded_length = read_24_le(&buf[1]);
        symbol_count = buf[4] + 1;
    }

    /* allocate decode table */
    decode_table_size = symbol_count * 2 - 1;
    decode_table = malloc(decode_table_size);
    CHECK_ERRNO(decode_table == NULL, "malloc");

    /* read decode table */
    get_bytes(infile, decode_table, decode_table_size);

#if 0
    printf("encoded size = %ld bytes (%d header + %ld body)\n",
            file_length, 5 + decode_table_size,
            file_length - (5 + decode_table_size));
    printf("decoded size = %ld bytes\n", decoded_length);
#endif

    /* decode */
    {
        uint32_t bits;
        int bits_left = 0;
        int table_offset = 0;
        long bytes_decoded = 0;

        while ( bytes_decoded < decoded_length )
        {
            if (bits_left == 0)
            {
                bits = get_32_le(infile);
                bits_left = 32;
            }

            int current_bit = ((bits & 0x80000000) != 0);
            int next_offset = ((table_offset + 1) / 2 * 2) + 1 +
                (decode_table[table_offset] & 0x3f) * 2 +
                (current_bit ? 1 : 0);

#if 0
            printf("%d %02x %lx => %lx\n", current_bit,
                    decode_table[table_offset],
                    (unsigned long)table_offset,
                    (unsigned long)next_offset);
#endif

            CHECK_ERROR (next_offset >= decode_table_size,
                    "reading past end of decode table");

            if ((!current_bit && (decode_table[table_offset] & 0x80)) ||
                ( current_bit && (decode_table[table_offset] & 0x40)))
            {
                CHECK_FILE(
                    fwrite(&decode_table[next_offset], 1, 1, outfile) != 1,
                    outfile, "fwrite");
                bytes_decoded++;
#if 0
                printf("%02x\n", decode_table[next_offset]);
                return;
#endif
                next_offset = 0;
            }

            CHECK_ERROR (next_offset == table_offset,
                    "stuck in a loop somehow");
            table_offset = next_offset;
            bits_left--;
            bits <<= 1;
        }
    }

#if 0
    printf("done\n");
#endif
}