aec.c 4.65 KB
Newer Older
1 2 3 4 5
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
6
#include <getopt.h>
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
7
#include "libaec.h"
8 9 10 11 12

#define CHUNK 1024

int main(int argc, char *argv[])
{
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
13
    struct aec_stream strm;
14 15
    unsigned char *in;
    unsigned char *out;
16 17
    int chunk, total_out, status, c;
    int input_avail, output_avail;
18
    char *outfn, *infn, *ext;
19 20
    FILE *infp, *outfp;
    int cflag = 0;
21
    int dflag = 0;
22 23

    chunk = CHUNK;
24 25
    strm.bit_per_sample = 8;
    strm.block_size = 8;
26
    strm.rsi = 2;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
27
    strm.flags = AEC_DATA_PREPROCESS;
28 29
    opterr = 0;

30
    while ((c = getopt (argc, argv, "d3Mscb:B:R:J:")) != -1)
31 32
        switch (c)
        {
33 34 35
        case 'd':
            dflag = 1;
            break;
36
        case 'b':
37
            chunk = atoi(optarg);
38
            break;
39 40 41
        case 'B':
            strm.bit_per_sample = atoi(optarg);
            break;
42 43 44
        case 'J':
            strm.block_size = atoi(optarg);
            break;
45 46
        case 'R':
            strm.rsi = atoi(optarg);
47
            break;
48 49 50
        case 'c':
            cflag = 1;
            break;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
51
        case 's':
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
52
            strm.flags |= AEC_DATA_SIGNED;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
53
            break;
54
        case 'M':
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
55
            strm.flags |= AEC_DATA_MSB;
56
            break;
57
        case '3':
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
58
            strm.flags |= AEC_DATA_3BYTE;
59
            break;
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
        case '?':
            if (optopt == 'b')
                fprintf (stderr, "Option -%c requires an argument.\n", optopt);
            else if (isprint (optopt))
                fprintf (stderr, "Unknown option `-%c'.\n", optopt);
            else
                fprintf (stderr,
                         "Unknown option character `\\x%x'.\n",
                         optopt);
            return 1;
        default:
            abort ();
        }

    if (optind < argc)
    {
        infn = argv[optind];
    }
    else
    {
        fprintf(stderr, "Usage: %s [ -c ] [ -b chunksize ] name\n", argv[0]);
        exit(-1);
    }

84 85
    if (strm.bit_per_sample > 16)
    {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
86
        if (strm.bit_per_sample <= 24 && strm.flags & AEC_DATA_3BYTE)
87 88 89 90 91 92 93 94 95
            chunk *= 3;
        else
            chunk *= 4;
    }
    else if (strm.bit_per_sample > 8)
    {
        chunk *= 2;
    }

96 97
    out = (unsigned char *)malloc(chunk);
    in = (unsigned char *)malloc(chunk);
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123


    if (in == NULL || out == NULL)
        exit(-1);

    total_out = 0;
    strm.avail_in = 0;
    strm.avail_out = chunk;
    strm.next_out = out;

    input_avail = 1;
    output_avail = 1;

    if ((infp = fopen(infn, "r")) == NULL)
        exit(-1);

    if (cflag)
    {
        outfp = stdout;
    }
    else
    {
        outfn = malloc(strlen(infn) + 4);
        if (outfn == NULL)
            exit(-1);

124 125
        if (dflag)
        {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
126
            if ((ext = strstr(infn, ".aec")) == NULL)
127
            {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
128
                fprintf(stderr, "Error: input file needs to end with .aec\n");
129 130 131 132 133 134
                exit(-1);
            }
            strncpy(outfn, infn, ext - infn);
        }
        else
        {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
135
            sprintf(outfn, "%s.aec", infn);
136
        }
137 138 139 140 141

        if ((outfp = fopen(outfn, "w")) == NULL)
            exit(-1);
    }

142 143
    if (dflag)
    {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
144
        if (aec_decode_init(&strm) != AEC_OK)
145 146 147 148
            return 1;
    }
    else
    {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
149
        if (aec_encode_init(&strm) != AEC_OK)
150 151 152
            return 1;
    }

153 154 155 156 157 158 159
    while(input_avail || output_avail)
    {
        if (strm.avail_in == 0 && input_avail)
        {
            strm.avail_in = fread(in, 1, chunk, infp);
            if (strm.avail_in != chunk)
                input_avail = 0;
160
            strm.next_in = in;
161 162
        }

163
        if (dflag)
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
164
            status = aec_decode(&strm, AEC_NO_FLUSH);
165
        else
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
166
            status = aec_encode(&strm, AEC_NO_FLUSH);
167

Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
168
        if (status != AEC_OK)
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
        {
            fprintf(stderr, "error is %i\n", status);
            return 1;
        }

        if (strm.total_out - total_out > 0)
        {
            fwrite(out, strm.total_out - total_out, 1, outfp);
            total_out = strm.total_out;
            output_avail = 1;
            strm.next_out = out;
            strm.avail_out = chunk;
        }
        else
        {
            output_avail = 0;
        }

    }

189
    if (dflag)
190
    {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
191
        aec_decode_end(&strm);
192
    }
193
    else
194
    {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
195
        if ((status = aec_encode(&strm, AEC_FLUSH)) != AEC_OK)
196 197 198 199 200 201 202 203 204 205
        {
            fprintf(stderr, "error is %i\n", status);
            return 1;
        }

        if (strm.total_out - total_out > 0)
        {
            fwrite(out, strm.total_out - total_out, 1, outfp);
        }

Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
206
        aec_encode_end(&strm);
207 208 209 210 211 212 213 214 215 216 217 218 219
    }

    fclose(infp);
    fclose(outfp);
    free(in);
    free(out);
    if (!cflag)
    {
        unlink(infn);
        free(outfn);
    }
    return 0;
}