allow ffmpeg video to resample curr_pos, add bluray format
[goodguy/history.git] / cinelerra-5.0 / quicktime / ulaw.c
1 #include "funcprotos.h"
2 #include "quicktime.h"
3 #include "ulaw.h"
4 #include <stdint.h>
5
6 typedef struct
7 {
8         float *ulawtofloat_table;
9         float *ulawtofloat_ptr;
10         int16_t *ulawtoint16_table;
11         int16_t *ulawtoint16_ptr;
12         unsigned char *int16toulaw_table;
13         unsigned char *int16toulaw_ptr;
14         unsigned char *read_buffer;
15         long read_size;
16 } quicktime_ulaw_codec_t;
17
18 /* ==================================== private for ulaw */
19
20 #define uBIAS 0x84
21 #define uCLIP 32635
22
23 int ulaw_init_ulawtofloat(quicktime_t *file, int track)
24 {
25         int i;
26         quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
27
28         if(!codec->ulawtofloat_table)
29         {
30         static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
31         int sign, exponent, mantissa, sample;
32                 unsigned char ulawbyte;
33
34                 codec->ulawtofloat_table = malloc(sizeof(float) * 256);
35                 codec->ulawtofloat_ptr = codec->ulawtofloat_table;
36                 for(i = 0; i < 256; i++)
37                 {
38                         ulawbyte = (unsigned char)i;
39                 ulawbyte = ~ulawbyte;
40                 sign = (ulawbyte & 0x80);
41                 exponent = (ulawbyte >> 4) & 0x07;
42                 mantissa = ulawbyte & 0x0F;
43                 sample = exp_lut[exponent] + (mantissa << (exponent + 3));
44                 if(sign != 0) sample = -sample;
45
46                         codec->ulawtofloat_ptr[i] = (float)sample / 32768;
47                 }
48         }
49         return 0;
50 }
51
52 float ulaw_bytetofloat(quicktime_ulaw_codec_t *codec, unsigned char input)
53 {
54         return codec->ulawtofloat_ptr[input];
55 }
56
57 int ulaw_init_ulawtoint16(quicktime_t *file, int track)
58 {
59         int i;
60         quicktime_audio_map_t *atrack = &(file->atracks[track]);
61         quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
62
63 /* We use the floating point table to get values for the 16 bit table */
64         ulaw_init_ulawtofloat(file, track);
65         if(!codec->ulawtoint16_table)
66         {
67                 codec->ulawtoint16_table = malloc(sizeof(int16_t) * 256);
68                 codec->ulawtoint16_ptr = codec->ulawtoint16_table;
69
70                 for(i = 0; i < 256; i++)
71                 {
72                         codec->ulawtoint16_table[i] = (int)(32768 * codec->ulawtofloat_ptr[i]);
73                 }
74         }
75         return 0;
76 }
77
78 int16_t ulaw_bytetoint16(quicktime_ulaw_codec_t *codec, unsigned char input)
79 {
80         return codec->ulawtoint16_ptr[input];
81 }
82
83 int ulaw_init_int16toulaw(quicktime_t *file, int track)
84 {
85         quicktime_audio_map_t *atrack = &(file->atracks[track]);
86         quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
87
88         if(!codec->int16toulaw_table)
89         {
90         int sign, exponent, mantissa;
91         unsigned char ulawbyte;
92                 int sample;
93                 int i;
94         int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
95                                4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
96                                5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
97                                5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
98                                6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
99                                6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
100                                6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
101                                6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
102                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
103                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
104                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
105                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
106                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
107                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
108                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
109                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
110
111                 codec->int16toulaw_table = malloc(65536);
112                 codec->int16toulaw_ptr = codec->int16toulaw_table + 32768;
113
114                 for(i = -32768; i < 32768; i++)
115                 {
116                         sample = i;
117 /* Get the sample into sign-magnitude. */
118                 sign = (sample >> 8) & 0x80;            /* set aside the sign */
119                 if(sign != 0) sample = -sample;         /* get magnitude */
120                 if(sample > uCLIP) sample = uCLIP;              /* clip the magnitude */
121
122 /* Convert from 16 bit linear to ulaw. */
123                 sample = sample + uBIAS;
124                     exponent = exp_lut[(sample >> 7) & 0xFF];
125                     mantissa = (sample >> (exponent + 3)) & 0x0F;
126                     ulawbyte = ~(sign | (exponent << 4) | mantissa);
127 #ifdef ZEROTRAP
128                     if (ulawbyte == 0) ulawbyte = 0x02;     /* optional CCITT trap */
129 #endif
130
131                     codec->int16toulaw_ptr[i] = ulawbyte;
132                 }
133         }
134         return 0;
135 }
136
137 float ulaw_int16tobyte(quicktime_ulaw_codec_t *codec, int16_t input)
138 {
139         return codec->int16toulaw_ptr[input];
140 }
141
142 float ulaw_floattobyte(quicktime_ulaw_codec_t *codec, float input)
143 {
144         return codec->int16toulaw_ptr[(int)(input * 32768)];
145 }
146
147
148 int ulaw_get_read_buffer(quicktime_t *file, int track, long samples)
149 {
150         quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
151
152         if(codec->read_buffer && codec->read_size != samples)
153         {
154                 free(codec->read_buffer);
155                 codec->read_buffer = 0;
156         }
157         
158         if(!codec->read_buffer) 
159         {
160                 int64_t bytes = samples * file->atracks[track].channels;
161                 codec->read_size = samples;
162                 if(!(codec->read_buffer = malloc(bytes))) return 1;
163         }
164         return 0;
165 }
166
167 int ulaw_delete_tables(quicktime_audio_map_t *atrack)
168 {
169         quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
170
171         if(codec->ulawtofloat_table) 
172         { 
173                 free(codec->ulawtofloat_table); 
174         }
175         if(codec->ulawtoint16_table) 
176         { 
177                 free(codec->ulawtoint16_table); 
178         }
179         if(codec->int16toulaw_table) 
180         { 
181                 free(codec->int16toulaw_table); 
182         }
183         if(codec->read_buffer) free(codec->read_buffer);
184         codec->int16toulaw_table = 0;
185         codec->ulawtoint16_table = 0;
186         codec->ulawtofloat_table = 0;
187         codec->read_buffer = 0;
188         codec->read_size = 0;
189         return 0;
190 }
191
192 /* =================================== public for ulaw */
193
194 static void quicktime_delete_codec_ulaw(quicktime_audio_map_t *atrack)
195 {
196         quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
197
198         ulaw_delete_tables(atrack);
199         free(codec);
200 }
201
202 static int quicktime_decode_ulaw(quicktime_t *file, 
203                                         int16_t *output_i, 
204                                         float *output_f, 
205                                         long samples, 
206                                         int track, 
207                                         int channel)
208 {
209         int result = 0;
210         quicktime_audio_map_t *track_map = &(file->atracks[track]);
211         quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
212
213         result = ulaw_get_read_buffer(file, track, samples);
214         
215         if(output_f) result += ulaw_init_ulawtofloat(file, track);
216         if(output_i) result += ulaw_init_ulawtoint16(file, track);
217
218         if(!result)
219         {
220                 result = !quicktime_read_audio(file, (char*)codec->read_buffer, samples, track);
221 // Undo increment since this is done in codecs.c
222                 track_map->current_position -= samples;
223
224 /*printf("quicktime_decode_ulaw %d\n", result); */
225                 if(!result)
226                 {
227                         if(output_f)
228                         {
229                                 unsigned char *input = &(codec->read_buffer[channel]);
230                                 float *output_ptr = output_f;
231                                 float *output_end = output_f + samples;
232                                 int step = file->atracks[track].channels;
233
234                                 while(output_ptr < output_end)
235                                 {
236                                         *output_ptr++ = ulaw_bytetofloat(codec, *input);
237                                         input += step;
238                                 }
239                         }
240                         else
241                         if(output_i)
242                         {
243                                 unsigned char *input = &(codec->read_buffer[channel]);
244                                 int16_t *output_ptr = output_i;
245                                 int16_t *output_end = output_i + samples;
246                                 int step = file->atracks[track].channels;
247
248                                 while(output_ptr < output_end)
249                                 {
250                                         *output_ptr++ = ulaw_bytetoint16(codec, *input);
251                                         input += step;
252                                 }
253                         }
254                 }
255         }
256
257         return result;
258 }
259
260 static int quicktime_encode_ulaw(quicktime_t *file, 
261                                                         int16_t **input_i, 
262                                                         float **input_f, 
263                                                         int track, 
264                                                         long samples)
265 {
266         int result = 0;
267         int channel, step;
268         quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
269         quicktime_atom_t chunk_atom;
270         quicktime_audio_map_t *track_map = &file->atracks[track];
271         quicktime_trak_t *trak = track_map->track;
272
273         result = ulaw_init_int16toulaw(file, track);
274         result += ulaw_get_read_buffer(file, track, samples);
275
276         if(!result)
277         {
278                 step = file->atracks[track].channels;
279
280                 if(input_f)
281                 {
282                         for(channel = 0; channel < file->atracks[track].channels; channel++)
283                         {
284                                 float *input_ptr = input_f[channel];
285                                 float *input_end = input_f[channel] + samples;
286                                 unsigned char *output = codec->read_buffer + channel;
287
288                                 while(input_ptr < input_end)
289                                 {
290                                         *output = ulaw_floattobyte(codec, *input_ptr++);
291                                         output += step;
292                                 }
293                         }
294                 }
295                 else
296                 if(input_i)
297                 {
298                         for(channel = 0; channel < file->atracks[track].channels; channel++)
299                         {
300                                 int16_t *input_ptr = input_i[channel];
301                                 int16_t *input_end = input_i[channel] + samples;
302                                 unsigned char *output = codec->read_buffer + channel;
303
304                                 while(input_ptr < input_end)
305                                 {
306                                         *output = ulaw_int16tobyte(codec, *input_ptr++);
307                                         output += step;
308                                 }
309                         }
310                 }
311
312                 quicktime_write_chunk_header(file, trak, &chunk_atom);
313                 result = quicktime_write_data(file, (char*)codec->read_buffer, 
314                         samples * file->atracks[track].channels);
315                 quicktime_write_chunk_footer(file, trak,
316                         track_map->current_chunk, &chunk_atom, samples);
317
318 /* defeat fwrite's return */
319                 if(result) 
320                         result = 0; 
321                 else 
322                         result = 1; 
323
324                 file->atracks[track].current_chunk++;           
325         }
326
327         return result;
328 }
329
330
331 void quicktime_init_codec_ulaw(quicktime_audio_map_t *atrack)
332 {
333         quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
334 //      quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
335
336 /* Init public items */
337         codec_base->priv = calloc(1, sizeof(quicktime_ulaw_codec_t));
338         codec_base->delete_acodec = quicktime_delete_codec_ulaw;
339         codec_base->decode_video = 0;
340         codec_base->encode_video = 0;
341         codec_base->decode_audio = quicktime_decode_ulaw;
342         codec_base->encode_audio = quicktime_encode_ulaw;
343         codec_base->fourcc = QUICKTIME_ULAW;
344         codec_base->title = "uLaw";
345         codec_base->desc = "uLaw";
346         codec_base->wav_id = 0x07;
347
348 /* Init private items */
349 }