1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /***************************************************************************
4
5 avhuff.c
6
7 Audio/video compression and decompression helpers.
8
9 ****************************************************************************
10
11 Each frame is compressed as a unit. The raw data is of the form:
12 (all multibyte values are stored in big-endian format)
13
14 +00 = 'chav' (4 bytes) - fixed header data to identify the format
15 +04 = metasize (1 byte) - size of metadata in bytes (max=255 bytes)
16 +05 = channels (1 byte) - number of audio channels
17 +06 = samples (2 bytes) - number of samples per audio stream
18 +08 = width (2 bytes) - width of video data
19 +0A = height (2 bytes) - height of video data
20 +0C = <metadata> - as raw bytes
21 <audio stream 0> - as signed 16-bit samples
22 <audio stream 1> - as signed 16-bit samples
23 ...
24 <video data> - as a raw array of 8-bit YUY data in (Cb,Y,Cr,Y) order
25
26 When compressed, the data is stored as follows:
27 (all multibyte values are stored in big-endian format)
28
29 +00 = metasize (1 byte) - size of metadata in bytes
30 +01 = channels (1 byte) - number of audio channels
31 +02 = samples (2 bytes) - number of samples per audio stream
32 +04 = width (2 bytes) - width of video data
33 +06 = height (2 bytes) - height of video data
34 +08 = audio huffman size (2 bytes) - size of audio huffman tables
35 (0x0000 => uncompressed deltas are used)
36 +0A = str0size (2 bytes) - compressed size of stream 0
37 +0C = str1size (2 bytes) - compressed size of stream 1
38 ...
39 <metadata> - as raw data
40 <audio huffman table> - Huffman table for audio decoding
41 <audio stream 0 data> - Huffman-compressed deltas
42 <audio stream 1 data> - Huffman-compressed deltas
43 <...>
44 <video huffman tables> - Huffman tables for video decoding
45 <video data> - compressed data
46
47 ****************************************************************************
48
49 Attempted techniques that have not been worthwhile:
50
51 * Attempted to use integer DCTs from the IJG code; even the "slow"
52 variants produce a lot of error and thus kill our compression ratio,
53 since our compression is based on error not bitrate.
54
55 * Tried various other predictors for the lossless video encoding, but
56 none tended to give any significant gain over predicting the
57 previous pixel.
58
59 ***************************************************************************/
60
61 #include <cassert>
62
63 #include "avhuff.h"
64 #include "huffman.h"
65 #include "chd.h"
66
67 #include <cmath>
68 #include <cstdlib>
69 #include <new>
70
71
72
73 //**************************************************************************
74 // INLINE FUNCTIONS
75 //**************************************************************************
76
77 //-------------------------------------------------
78 // code_to_rlecount - number of RLE repetitions
79 // encoded in a given byte
80 //-------------------------------------------------
81
code_to_rlecount(int code)82 inline int code_to_rlecount(int code)
83 {
84 if (code == 0x00)
85 return 1;
86 if (code <= 0x107)
87 return 8 + (code - 0x100);
88 return 16 << (code - 0x108);
89 }
90
91
92 //-------------------------------------------------
93 // rlecount_to_byte - return a byte encoding
94 // the maximum RLE count less than or equal to
95 // the provided amount
96 //-------------------------------------------------
97
rlecount_to_code(int rlecount)98 inline int rlecount_to_code(int rlecount)
99 {
100 if (rlecount >= 2048)
101 return 0x10f;
102 if (rlecount >= 1024)
103 return 0x10e;
104 if (rlecount >= 512)
105 return 0x10d;
106 if (rlecount >= 256)
107 return 0x10c;
108 if (rlecount >= 128)
109 return 0x10b;
110 if (rlecount >= 64)
111 return 0x10a;
112 if (rlecount >= 32)
113 return 0x109;
114 if (rlecount >= 16)
115 return 0x108;
116 if (rlecount >= 8)
117 return 0x100 + (rlecount - 8);
118 return 0x00;
119 }
120
121
122 //-------------------------------------------------
123 // encode_one - encode data
124 //-------------------------------------------------
125
encode_one(bitstream_out & bitbuf,uint16_t * & rleptr)126 inline void avhuff_encoder::deltarle_encoder::encode_one(bitstream_out &bitbuf, uint16_t *&rleptr)
127 {
128 // return RLE data if we still have some
129 if (m_rlecount != 0)
130 {
131 m_rlecount--;
132 return;
133 }
134
135 // fetch the data and process
136 uint16_t data = *rleptr++;
137 m_encoder.encode_one(bitbuf, data);
138 if (data >= 0x100)
139 m_rlecount = code_to_rlecount(data) - 1;
140 }
141
142
143 //-------------------------------------------------
144 // decode_one - decode data
145 //-------------------------------------------------
decode_one(bitstream_in & bitbuf)146 inline uint32_t avhuff_decoder::deltarle_decoder::decode_one(bitstream_in &bitbuf)
147 {
148 // return RLE data if we still have some
149 if (m_rlecount != 0)
150 {
151 m_rlecount--;
152 return m_prevdata;
153 }
154
155 // fetch the data and process
156 int data = m_decoder.decode_one(bitbuf);
157 if (data < 0x100)
158 {
159 m_prevdata += uint8_t(data);
160 return m_prevdata;
161 }
162 else
163 {
164 m_rlecount = code_to_rlecount(data);
165 m_rlecount--;
166 return m_prevdata;
167 }
168 }
169
170
171
172 //**************************************************************************
173 // AVHUFF ENCODER
174 //**************************************************************************
175
176 /**
177 * @fn avhuff_encoder::avhuff_encoder()
178 *
179 * @brief -------------------------------------------------
180 * avhuff_encoder - constructor
181 * -------------------------------------------------.
182 */
183
avhuff_encoder()184 avhuff_encoder::avhuff_encoder()
185 {
186 m_flac_encoder.set_sample_rate(48000);
187 m_flac_encoder.set_num_channels(1);
188 m_flac_encoder.set_strip_metadata(true);
189 }
190
191 /**
192 * @fn avhuff_error avhuff_encoder::encode_data(const uint8_t *source, uint8_t *dest, uint32_t &complength)
193 *
194 * @brief -------------------------------------------------
195 * encode_data - encode a block of data into a compressed data stream
196 * -------------------------------------------------.
197 *
198 * @param source Source for the.
199 * @param [in,out] dest If non-null, destination for the.
200 * @param [in,out] complength The complength.
201 *
202 * @return An avhuff_error.
203 */
204
encode_data(const uint8_t * source,uint8_t * dest,uint32_t & complength)205 avhuff_error avhuff_encoder::encode_data(const uint8_t *source, uint8_t *dest, uint32_t &complength)
206 {
207 // validate the header
208 if (source[0] != 'c' || source[1] != 'h' || source[2] != 'a' || source[3] != 'v')
209 return AVHERR_INVALID_DATA;
210
211 // extract info from the header
212 uint32_t metasize = source[4];
213 uint32_t channels = source[5];
214 uint32_t samples = (source[6] << 8) + source[7];
215 uint32_t width = (source[8] << 8) + source[9];
216 uint32_t height = (source[10] << 8) + source[11];
217 source += 12;
218
219 // write the basics to the new header
220 dest[0] = metasize;
221 dest[1] = channels;
222 dest[2] = samples >> 8;
223 dest[3] = samples;
224 dest[4] = width >> 8;
225 dest[5] = width;
226 dest[6] = height >> 8;
227 dest[7] = height;
228
229 // starting offsets
230 uint32_t dstoffs = 10 + 2 * channels;
231
232 // copy the metadata first
233 if (metasize > 0)
234 {
235 memcpy(dest + dstoffs, source, metasize);
236 source += metasize;
237 dstoffs += metasize;
238 }
239
240 // encode the audio channels
241 if (channels > 0)
242 {
243 // encode the audio
244 avhuff_error err = encode_audio(source, channels, samples, dest + dstoffs, &dest[8]);
245 source += channels * samples * 2;
246 if (err != AVHERR_NONE)
247 return err;
248
249 // advance the pointers past the data
250 uint16_t treesize = (dest[8] << 8) + dest[9];
251 if (treesize != 0xffff)
252 dstoffs += treesize;
253 for (int chnum = 0; chnum < channels; chnum++)
254 dstoffs += (dest[10 + 2 * chnum] << 8) + dest[11 + 2 * chnum];
255 }
256 else
257 {
258 dest[8] = 0;
259 dest[9] = 0;
260 }
261
262 // encode the video data
263 if (width > 0 && height > 0)
264 {
265 // encode the video
266 uint32_t vidlength = 0;
267 avhuff_error err = encode_video(source, width, height, dest + dstoffs, vidlength);
268 if (err != AVHERR_NONE)
269 return err;
270
271 // advance the pointers past the data
272 dstoffs += vidlength;
273 }
274
275 // set the total compression
276 complength = dstoffs;
277 return AVHERR_NONE;
278 }
279
280 /**
281 * @fn uint32_t avhuff_encoder::raw_data_size(const uint8_t *data)
282 *
283 * @brief -------------------------------------------------
284 * raw_data_size - return the raw data size of a raw stream based on the header
285 * -------------------------------------------------.
286 *
287 * @param data The data.
288 *
289 * @return An uint32_t.
290 */
291
raw_data_size(const uint8_t * data)292 uint32_t avhuff_encoder::raw_data_size(const uint8_t *data)
293 {
294 // make sure we have a correct header
295 int size = 0;
296 if (data[0] == 'c' && data[1] == 'h' && data[2] == 'a' && data[3] == 'v')
297 {
298 // add in header size plus metadata length
299 size = 12 + data[4];
300
301 // add in channels * samples
302 size += 2 * data[5] * ((data[6] << 8) + data[7]);
303
304 // add in 2 * width * height
305 size += 2 * ((data[8] << 8) + data[9]) * (((data[10] << 8) + data[11]) & 0x7fff);
306 }
307 return size;
308 }
309
310 /**
311 * @fn avhuff_error avhuff_encoder::assemble_data(std::vector<uint8_t> &buffer, bitmap_yuy16 &bitmap, uint8_t channels, uint32_t numsamples, int16_t **samples, uint8_t *metadata, uint32_t metadatasize)
312 *
313 * @brief -------------------------------------------------
314 * assemble_data - assemble a datastream from raw bits
315 * -------------------------------------------------.
316 *
317 * @param [in,out] buffer The buffer.
318 * @param [in,out] bitmap The bitmap.
319 * @param channels The channels.
320 * @param numsamples The numsamples.
321 * @param [in,out] samples If non-null, the samples.
322 * @param [in,out] metadata If non-null, the metadata.
323 * @param metadatasize The metadatasize.
324 *
325 * @return An avhuff_error.
326 */
327
assemble_data(std::vector<uint8_t> & buffer,bitmap_yuy16 & bitmap,uint8_t channels,uint32_t numsamples,int16_t ** samples,uint8_t * metadata,uint32_t metadatasize)328 avhuff_error avhuff_encoder::assemble_data(std::vector<uint8_t> &buffer, bitmap_yuy16 &bitmap, uint8_t channels, uint32_t numsamples, int16_t **samples, uint8_t *metadata, uint32_t metadatasize)
329 {
330 // sanity check the inputs
331 if (metadatasize > 255)
332 return AVHERR_METADATA_TOO_LARGE;
333 if (numsamples > 65535)
334 return AVHERR_AUDIO_TOO_LARGE;
335 if (bitmap.width() > 65535 || bitmap.height() > 65535)
336 return AVHERR_VIDEO_TOO_LARGE;
337
338 // fill in the header
339 buffer.resize(12 + metadatasize + numsamples * channels * 2 + bitmap.width() * bitmap.height() * 2);
340 uint8_t *dest = &buffer[0];
341 *dest++ = 'c';
342 *dest++ = 'h';
343 *dest++ = 'a';
344 *dest++ = 'v';
345 *dest++ = metadatasize;
346 *dest++ = channels;
347 *dest++ = numsamples >> 8;
348 *dest++ = numsamples & 0xff;
349 *dest++ = bitmap.width() >> 8;
350 *dest++ = bitmap.width() & 0xff;
351 *dest++ = bitmap.height() >> 8;
352 *dest++ = bitmap.height() & 0xff;
353
354 // copy the metadata
355 if (metadatasize > 0)
356 memcpy(dest, metadata, metadatasize);
357 dest += metadatasize;
358
359 // copy the audio streams
360 for (uint8_t curchan = 0; curchan < channels; curchan++)
361 for (uint32_t cursamp = 0; cursamp < numsamples; cursamp++)
362 {
363 *dest++ = samples[curchan][cursamp] >> 8;
364 *dest++ = samples[curchan][cursamp] & 0xff;
365 }
366
367 // copy the video data
368 for (int32_t y = 0; y < bitmap.height(); y++)
369 {
370 uint16_t *src = &bitmap.pix(y);
371 for (int32_t x = 0; x < bitmap.width(); x++)
372 {
373 *dest++ = src[x] >> 8;
374 *dest++ = src[x] & 0xff;
375 }
376 }
377 return AVHERR_NONE;
378 }
379
380 /**
381 * @fn avhuff_error avhuff_encoder::encode_audio(const uint8_t *source, int channels, int samples, uint8_t *dest, uint8_t *sizes)
382 *
383 * @brief -------------------------------------------------
384 * encode_audio - encode raw audio data to the destination
385 * -------------------------------------------------.
386 *
387 * @param source Source for the.
388 * @param channels The channels.
389 * @param samples The samples.
390 * @param [in,out] dest If non-null, destination for the.
391 * @param [in,out] sizes If non-null, the sizes.
392 *
393 * @return An avhuff_error.
394 */
395
encode_audio(const uint8_t * source,int channels,int samples,uint8_t * dest,uint8_t * sizes)396 avhuff_error avhuff_encoder::encode_audio(const uint8_t *source, int channels, int samples, uint8_t *dest, uint8_t *sizes)
397 {
398 #if AVHUFF_USE_FLAC
399
400 // input data is big-endian; determine our platform endianness
401 uint16_t be_test = 0;
402 *(uint8_t *)&be_test = 1;
403 bool swap_endian = (be_test == 1);
404
405 // set huffman tree size to 0xffff to indicate FLAC
406 sizes[0] = 0xff;
407 sizes[1] = 0xff;
408
409 // set the block size for this round and iterate over channels
410 m_flac_encoder.set_block_size(samples);
411 for (int chnum = 0; chnum < channels; chnum++)
412 {
413 // encode the data
414 m_flac_encoder.reset(dest, samples * 2);
415 if (!m_flac_encoder.encode_interleaved(reinterpret_cast<const int16_t *>(source) + chnum * samples, samples, swap_endian))
416 return AVHERR_COMPRESSION_ERROR;
417
418 // set the size for this channel
419 uint32_t cursize = m_flac_encoder.finish();
420 sizes[chnum * 2 + 2] = cursize >> 8;
421 sizes[chnum * 2 + 3] = cursize;
422 dest += cursize;
423 }
424
425 #else
426
427 // expand the delta buffer if needed
428 m_audiobuffer.resize(channels * samples * 2);
429 uint8_t *deltabuf = m_audiobuffer;
430
431 // iterate over channels to compute deltas
432 m_audiohi_encoder.histo_reset();
433 m_audiolo_encoder.histo_reset();
434 for (int chnum = 0; chnum < channels; chnum++)
435 {
436 // extract audio data into hi and lo deltas stored in big-endian order
437 int16_t prevsample = 0;
438 for (int sampnum = 0; sampnum < samples; sampnum++)
439 {
440 int16_t newsample = (source[0] << 8) | source[1];
441 source += 2;
442
443 int16_t delta = newsample - prevsample;
444 prevsample = newsample;
445 m_audiohi_encoder.histo_one(*deltabuf++ = delta >> 8);
446 m_audiolo_encoder.histo_one(*deltabuf++ = delta);
447 }
448 }
449
450 // compute the trees
451 huffman_error hufferr = m_audiohi_encoder.compute_tree_from_histo();
452 if (hufferr != HUFFERR_NONE)
453 return AVHERR_COMPRESSION_ERROR;
454 hufferr = m_audiolo_encoder.compute_tree_from_histo();
455 if (hufferr != HUFFERR_NONE)
456 return AVHERR_COMPRESSION_ERROR;
457
458 // export the trees to the output
459 bitstream_out bitbuf(dest, 2 * channels * samples);
460 hufferr = m_audiohi_encoder.export_tree_rle(bitbuf);
461 if (hufferr != HUFFERR_NONE)
462 return AVHERR_COMPRESSION_ERROR;
463 bitbuf.flush();
464 hufferr = m_audiolo_encoder.export_tree_rle(bitbuf);
465 if (hufferr != HUFFERR_NONE)
466 return AVHERR_COMPRESSION_ERROR;
467
468 // note the size of the two trees
469 uint32_t huffsize = bitbuf.flush();
470 sizes[0] = huffsize >> 8;
471 sizes[1] = huffsize;
472
473 // iterate over channels
474 uint32_t totalsize = huffsize;
475 int chnum;
476 for (chnum = 0; chnum < channels; chnum++)
477 {
478 // encode the data
479 const uint8_t *input = m_audiobuffer + chnum * samples * 2;
480 for (int sampnum = 0; sampnum < samples; sampnum++)
481 {
482 m_audiohi_encoder.encode_one(bitbuf, *input++);
483 m_audiolo_encoder.encode_one(bitbuf, *input++);
484 }
485
486 // store the size of this stream
487 uint32_t cursize = bitbuf.flush() - totalsize;
488 totalsize += cursize;
489 if (totalsize >= channels * samples * 2)
490 break;
491 sizes[chnum * 2 + 2] = cursize >> 8;
492 sizes[chnum * 2 + 3] = cursize;
493 }
494
495 // if we ran out of room, throw it all away and just store raw
496 if (chnum < channels)
497 {
498 memcpy(dest, m_audiobuffer, channels * samples * 2);
499 uint32_t size = samples * 2;
500 sizes[0] = sizes[1] = 0;
501 for (chnum = 0; chnum < channels; chnum++)
502 {
503 sizes[chnum * 2 + 2] = size >> 8;
504 sizes[chnum * 2 + 3] = size;
505 }
506 }
507
508 #endif
509
510 return AVHERR_NONE;
511 }
512
513 /**
514 * @fn avhuff_error avhuff_encoder::encode_video(const uint8_t *source, int width, int height, uint8_t *dest, uint32_t &complength)
515 *
516 * @brief -------------------------------------------------
517 * encode_video - encode raw video data to the destination
518 * -------------------------------------------------.
519 *
520 * @param source Source for the.
521 * @param width The width.
522 * @param height The height.
523 * @param [in,out] dest If non-null, destination for the.
524 * @param [in,out] complength The complength.
525 *
526 * @return An avhuff_error.
527 */
528
encode_video(const uint8_t * source,int width,int height,uint8_t * dest,uint32_t & complength)529 avhuff_error avhuff_encoder::encode_video(const uint8_t *source, int width, int height, uint8_t *dest, uint32_t &complength)
530 {
531 // only lossless supported at this time
532 return encode_video_lossless(source, width, height, dest, complength);
533 }
534
535 /**
536 * @fn avhuff_error avhuff_encoder::encode_video_lossless(const uint8_t *source, int width, int height, uint8_t *dest, uint32_t &complength)
537 *
538 * @brief -------------------------------------------------
539 * encode_video_lossless - do a lossless video encoding using deltas and huffman
540 * encoding
541 * -------------------------------------------------.
542 *
543 * @param source Source for the.
544 * @param width The width.
545 * @param height The height.
546 * @param [in,out] dest If non-null, destination for the.
547 * @param [in,out] complength The complength.
548 *
549 * @return An avhuff_error.
550 */
551
encode_video_lossless(const uint8_t * source,int width,int height,uint8_t * dest,uint32_t & complength)552 avhuff_error avhuff_encoder::encode_video_lossless(const uint8_t *source, int width, int height, uint8_t *dest, uint32_t &complength)
553 {
554 // set up the output; first byte is 0x80 to indicate lossless encoding
555 bitstream_out bitbuf(dest, width * height * 2);
556 bitbuf.write(0x80, 8);
557
558 // compute the histograms for the data
559 uint16_t *yrle = m_ycontext.rle_and_histo_bitmap(source + 0, width, 2, height);
560 uint16_t *cbrle = m_cbcontext.rle_and_histo_bitmap(source + 1, width / 2, 4, height);
561 uint16_t *crrle = m_crcontext.rle_and_histo_bitmap(source + 3, width / 2, 4, height);
562
563 // export the trees to the data stream
564 huffman_error hufferr = m_ycontext.export_tree_rle(bitbuf);
565 if (hufferr != HUFFERR_NONE)
566 return AVHERR_COMPRESSION_ERROR;
567 bitbuf.flush();
568 hufferr = m_cbcontext.export_tree_rle(bitbuf);
569 if (hufferr != HUFFERR_NONE)
570 return AVHERR_COMPRESSION_ERROR;
571 bitbuf.flush();
572 hufferr = m_crcontext.export_tree_rle(bitbuf);
573 if (hufferr != HUFFERR_NONE)
574 return AVHERR_COMPRESSION_ERROR;
575 bitbuf.flush();
576
577 // encode the data using the trees
578 for (uint32_t sy = 0; sy < height; sy++)
579 {
580 m_ycontext.flush_rle();
581 m_cbcontext.flush_rle();
582 m_crcontext.flush_rle();
583 for (uint32_t sx = 0; sx < width / 2; sx++)
584 {
585 m_ycontext.encode_one(bitbuf, yrle);
586 m_cbcontext.encode_one(bitbuf, cbrle);
587 m_ycontext.encode_one(bitbuf, yrle);
588 m_crcontext.encode_one(bitbuf, crrle);
589 }
590 }
591
592 // set the final length
593 complength = bitbuf.flush();
594 return AVHERR_NONE;
595 }
596
597
598
599 //**************************************************************************
600 // DELTA-RLE ENCODER
601 //**************************************************************************
602
603 /**
604 * @fn uint16_t *avhuff_encoder::deltarle_encoder::rle_and_histo_bitmap(const uint8_t *source, uint32_t items_per_row, uint32_t item_advance, uint32_t row_count)
605 *
606 * @brief -------------------------------------------------
607 * rle_and_histo_bitmap - RLE compress and histogram a bitmap's worth of data
608 * -------------------------------------------------.
609 *
610 * @param source Source for the.
611 * @param items_per_row The items per row.
612 * @param item_advance The item advance.
613 * @param row_count Number of rows.
614 *
615 * @return null if it fails, else an uint16_t*.
616 */
617
rle_and_histo_bitmap(const uint8_t * source,uint32_t items_per_row,uint32_t item_advance,uint32_t row_count)618 uint16_t *avhuff_encoder::deltarle_encoder::rle_and_histo_bitmap(const uint8_t *source, uint32_t items_per_row, uint32_t item_advance, uint32_t row_count)
619 {
620 // resize our RLE buffer
621 m_rlebuffer.resize(items_per_row * row_count);
622 uint16_t *dest = &m_rlebuffer[0];
623
624 // iterate over rows
625 m_encoder.histo_reset();
626 uint8_t prevdata = 0;
627 for (uint32_t row = 0; row < row_count; row++)
628 {
629 const uint8_t *end = source + items_per_row * item_advance;
630 for ( ; source < end; source += item_advance)
631 {
632 // fetch current data
633 uint8_t curdelta = *source - prevdata;
634 prevdata = *source;
635
636 // 0 deltas scan forward for a count
637 if (curdelta == 0)
638 {
639 int zerocount = 1;
640
641 // count the number of consecutive values
642 const uint8_t *scandata;
643 for (scandata = source + item_advance; scandata < end; scandata += item_advance)
644 if (*scandata == prevdata)
645 zerocount++;
646 else
647 break;
648
649 // if we hit the end of a row, maximize the count
650 if (scandata >= end && zerocount >= 8)
651 zerocount = 100000;
652
653 // encode the maximal count we can
654 int rlecode = rlecount_to_code(zerocount);
655 m_encoder.histo_one(*dest++ = rlecode);
656
657 // advance past the run
658 source += (code_to_rlecount(rlecode) - 1) * item_advance;
659 }
660
661 // otherwise, encode the actual data
662 else
663 m_encoder.histo_one(*dest++ = curdelta);
664 }
665
666 // advance to the next row
667 source = end;
668 }
669
670 // compute the tree for our histogram
671 m_encoder.compute_tree_from_histo();
672 return &m_rlebuffer[0];
673 }
674
675
676
677 //**************************************************************************
678 // AVHUFF DECODER
679 //**************************************************************************
680
681 /**
682 * @fn avhuff_decoder::avhuff_decoder()
683 *
684 * @brief -------------------------------------------------
685 * avhuff_decoder - constructor
686 * -------------------------------------------------.
687 */
688
avhuff_decoder()689 avhuff_decoder::avhuff_decoder()
690 {
691 }
692
693 /**
694 * @fn void avhuff_decoder::configure(const config &cfg)
695 *
696 * @brief -------------------------------------------------
697 * configure - configure decompression parameters
698 * -------------------------------------------------.
699 *
700 * @param cfg The configuration.
701 */
702
configure(const config & cfg)703 void avhuff_decoder::configure(const config &cfg)
704 {
705 m_video.wrap(*cfg.video, cfg.video->cliprect());
706 m_config = cfg;
707 }
708
709 /**
710 * @fn avhuff_error avhuff_decoder::decode_data(const uint8_t *source, uint32_t complength, uint8_t *dest)
711 *
712 * @brief -------------------------------------------------
713 * decode_data - decode both audio and video from a raw data stream
714 * -------------------------------------------------.
715 *
716 * @param source Source for the.
717 * @param complength The complength.
718 * @param [in,out] dest If non-null, destination for the.
719 *
720 * @return An avhuff_error.
721 */
722
decode_data(const uint8_t * source,uint32_t complength,uint8_t * dest)723 avhuff_error avhuff_decoder::decode_data(const uint8_t *source, uint32_t complength, uint8_t *dest)
724 {
725 // extract info from the header
726 if (complength < 8)
727 return AVHERR_INVALID_DATA;
728 uint32_t metasize = source[0];
729 uint32_t channels = source[1];
730 uint32_t samples = (source[2] << 8) + source[3];
731 uint32_t width = (source[4] << 8) + source[5];
732 uint32_t height = (source[6] << 8) + source[7];
733
734 // validate that the sizes make sense
735 if (complength < 10 + 2 * channels)
736 return AVHERR_INVALID_DATA;
737 uint32_t totalsize = 10 + 2 * channels;
738 uint32_t treesize = (source[8] << 8) | source[9];
739 if (treesize != 0xffff)
740 totalsize += treesize;
741 for (int chnum = 0; chnum < channels; chnum++)
742 totalsize += (source[10 + 2 * chnum] << 8) | source[11 + 2 * chnum];
743 if (totalsize >= complength)
744 return AVHERR_INVALID_DATA;
745
746 // starting offsets
747 uint32_t srcoffs = 10 + 2 * channels;
748
749 // if we are decoding raw, set up the output parameters
750 uint8_t *metastart, *videostart, *audiostart[16];
751 uint32_t audioxor, videoxor, videostride;
752 if (dest != nullptr)
753 {
754 // create a header
755 dest[0] = 'c';
756 dest[1] = 'h';
757 dest[2] = 'a';
758 dest[3] = 'v';
759 dest[4] = metasize;
760 dest[5] = channels;
761 dest[6] = samples >> 8;
762 dest[7] = samples;
763 dest[8] = width >> 8;
764 dest[9] = width;
765 dest[10] = height >> 8;
766 dest[11] = height;
767 dest += 12;
768
769 // determine the start of each piece of data
770 metastart = dest;
771 dest += metasize;
772 for (int chnum = 0; chnum < channels; chnum++)
773 {
774 audiostart[chnum] = dest;
775 dest += 2 * samples;
776 }
777 videostart = dest;
778
779 // data is assumed to be big-endian already
780 audioxor = videoxor = 0;
781 videostride = 2 * width;
782 }
783
784 // otherwise, extract from the state
785 else
786 {
787 // determine the start of each piece of data
788 metastart = m_config.metadata;
789 for (int chnum = 0; chnum < channels; chnum++)
790 audiostart[chnum] = reinterpret_cast<uint8_t *>(m_config.audio[chnum]);
791 videostart = m_video.valid() ? reinterpret_cast<uint8_t *>(&m_video.pix(0)) : nullptr;
792 videostride = m_video.valid() ? m_video.rowpixels() * 2 : 0;
793
794 // data is assumed to be native-endian
795 uint16_t betest = 0;
796 *(uint8_t *)&betest = 1;
797 audioxor = videoxor = (betest == 1) ? 1 : 0;
798
799 // verify against sizes
800 if (m_video.valid() && (m_video.width() < width || m_video.height() < height))
801 return AVHERR_VIDEO_TOO_LARGE;
802 for (int chnum = 0; chnum < channels; chnum++)
803 if (m_config.audio[chnum] != nullptr && m_config.maxsamples < samples)
804 return AVHERR_AUDIO_TOO_LARGE;
805 if (m_config.metadata != nullptr && m_config.maxmetalength < metasize)
806 return AVHERR_METADATA_TOO_LARGE;
807
808 // set the output values
809 if (m_config.actsamples != nullptr)
810 *m_config.actsamples = samples;
811 if (m_config.actmetalength != nullptr)
812 *m_config.actmetalength = metasize;
813 }
814
815 // copy the metadata first
816 if (metasize > 0)
817 {
818 if (metastart != nullptr)
819 memcpy(metastart, source + srcoffs, metasize);
820 srcoffs += metasize;
821 }
822
823 // decode the audio channels
824 if (channels > 0)
825 {
826 // decode the audio
827 avhuff_error err = decode_audio(channels, samples, source + srcoffs, audiostart, audioxor, &source[8]);
828 if (err != AVHERR_NONE)
829 return err;
830
831 // advance the pointers past the data
832 treesize = (source[8] << 8) + source[9];
833 if (treesize != 0xffff)
834 srcoffs += treesize;
835 for (int chnum = 0; chnum < channels; chnum++)
836 srcoffs += (source[10 + 2 * chnum] << 8) + source[11 + 2 * chnum];
837 }
838
839 // decode the video data
840 if (width > 0 && height > 0 && videostart != nullptr)
841 {
842 // decode the video
843 avhuff_error err = decode_video(width, height, source + srcoffs, complength - srcoffs, videostart, videostride, videoxor);
844 if (err != AVHERR_NONE)
845 return err;
846 }
847 return AVHERR_NONE;
848 }
849
850 /**
851 * @fn avhuff_error avhuff_decoder::decode_audio(int channels, int samples, const uint8_t *source, uint8_t **dest, uint32_t dxor, const uint8_t *sizes)
852 *
853 * @brief -------------------------------------------------
854 * decode_audio - decode audio from a compressed data stream
855 * -------------------------------------------------.
856 *
857 * @exception CHDERR_DECOMPRESSION_ERROR Thrown when a chderr decompression error error
858 * condition occurs.
859 *
860 * @param channels The channels.
861 * @param samples The samples.
862 * @param source Source for the.
863 * @param [in,out] dest If non-null, destination for the.
864 * @param dxor The dxor.
865 * @param sizes The sizes.
866 *
867 * @return An avhuff_error.
868 */
869
decode_audio(int channels,int samples,const uint8_t * source,uint8_t ** dest,uint32_t dxor,const uint8_t * sizes)870 avhuff_error avhuff_decoder::decode_audio(int channels, int samples, const uint8_t *source, uint8_t **dest, uint32_t dxor, const uint8_t *sizes)
871 {
872 // extract the huffman trees
873 uint16_t treesize = (sizes[0] << 8) | sizes[1];
874
875 #if AVHUFF_USE_FLAC
876
877 // if the tree size is 0xffff, the streams are FLAC-encoded
878 if (treesize == 0xffff)
879 {
880 // output data is big-endian; determine our platform endianness
881 uint16_t be_test = 0;
882 *(uint8_t *)&be_test = 1;
883 bool swap_endian = (be_test == 1);
884 if (dxor != 0)
885 swap_endian = !swap_endian;
886
887 // loop over channels
888 for (int chnum = 0; chnum < channels; chnum++)
889 {
890 // extract the size of this channel
891 uint16_t size = (sizes[chnum * 2 + 2] << 8) | sizes[chnum * 2 + 3];
892
893 // only process if the data is requested
894 uint8_t *curdest = dest[chnum];
895 if (curdest != nullptr)
896 {
897 // reset and decode
898 if (!m_flac_decoder.reset(48000, 1, samples, source, size))
899 throw CHDERR_DECOMPRESSION_ERROR;
900 if (!m_flac_decoder.decode_interleaved(reinterpret_cast<int16_t *>(curdest), samples, swap_endian))
901 throw CHDERR_DECOMPRESSION_ERROR;
902
903 // finish up
904 m_flac_decoder.finish();
905 }
906
907 // advance to the next channel's data
908 source += size;
909 }
910 return AVHERR_NONE;
911 }
912
913 #endif
914
915 // if we have a non-zero tree size, extract the trees
916 if (treesize != 0)
917 {
918 bitstream_in bitbuf(source, treesize);
919 huffman_error hufferr = m_audiohi_decoder.import_tree_rle(bitbuf);
920 if (hufferr != HUFFERR_NONE)
921 return AVHERR_INVALID_DATA;
922 bitbuf.flush();
923 hufferr = m_audiolo_decoder.import_tree_rle(bitbuf);
924 if (hufferr != HUFFERR_NONE)
925 return AVHERR_INVALID_DATA;
926 if (bitbuf.flush() != treesize)
927 return AVHERR_INVALID_DATA;
928 source += treesize;
929 }
930
931 // loop over channels
932 for (int chnum = 0; chnum < channels; chnum++)
933 {
934 // extract the size of this channel
935 uint16_t size = (sizes[chnum * 2 + 2] << 8) | sizes[chnum * 2 + 3];
936
937 // only process if the data is requested
938 uint8_t *curdest = dest[chnum];
939 if (curdest != nullptr)
940 {
941 int16_t prevsample = 0;
942
943 // if no huffman length, just copy the data
944 if (treesize == 0)
945 {
946 const uint8_t *cursource = source;
947 for (int sampnum = 0; sampnum < samples; sampnum++)
948 {
949 int16_t delta = (cursource[0] << 8) | cursource[1];
950 cursource += 2;
951
952 int16_t newsample = prevsample + delta;
953 prevsample = newsample;
954
955 curdest[0 ^ dxor] = newsample >> 8;
956 curdest[1 ^ dxor] = newsample;
957 curdest += 2;
958 }
959 }
960
961 // otherwise, Huffman-decode the data
962 else
963 {
964 bitstream_in bitbuf(source, size);
965 for (int sampnum = 0; sampnum < samples; sampnum++)
966 {
967 int16_t delta = m_audiohi_decoder.decode_one(bitbuf) << 8;
968 delta |= m_audiolo_decoder.decode_one(bitbuf);
969
970 int16_t newsample = prevsample + delta;
971 prevsample = newsample;
972
973 curdest[0 ^ dxor] = newsample >> 8;
974 curdest[1 ^ dxor] = newsample;
975 curdest += 2;
976 }
977 if (bitbuf.overflow())
978 return AVHERR_INVALID_DATA;
979 }
980 }
981
982 // advance to the next channel's data
983 source += size;
984 }
985 return AVHERR_NONE;
986 }
987
988 /**
989 * @fn avhuff_error avhuff_decoder::decode_video(int width, int height, const uint8_t *source, uint32_t complength, uint8_t *dest, uint32_t dstride, uint32_t dxor)
990 *
991 * @brief -------------------------------------------------
992 * decode_video - decode video from a compressed data stream
993 * -------------------------------------------------.
994 *
995 * @param width The width.
996 * @param height The height.
997 * @param source Source for the.
998 * @param complength The complength.
999 * @param [in,out] dest If non-null, destination for the.
1000 * @param dstride The dstride.
1001 * @param dxor The dxor.
1002 *
1003 * @return An avhuff_error.
1004 */
1005
decode_video(int width,int height,const uint8_t * source,uint32_t complength,uint8_t * dest,uint32_t dstride,uint32_t dxor)1006 avhuff_error avhuff_decoder::decode_video(int width, int height, const uint8_t *source, uint32_t complength, uint8_t *dest, uint32_t dstride, uint32_t dxor)
1007 {
1008 // if the high bit of the first byte is set, we decode losslessly
1009 if (source[0] & 0x80)
1010 return decode_video_lossless(width, height, source, complength, dest, dstride, dxor);
1011 else
1012 return AVHERR_INVALID_DATA;
1013 }
1014
1015 /**
1016 * @fn avhuff_error avhuff_decoder::decode_video_lossless(int width, int height, const uint8_t *source, uint32_t complength, uint8_t *dest, uint32_t dstride, uint32_t dxor)
1017 *
1018 * @brief -------------------------------------------------
1019 * decode_video_lossless - do a lossless video decoding using deltas and huffman
1020 * encoding
1021 * -------------------------------------------------.
1022 *
1023 * @param width The width.
1024 * @param height The height.
1025 * @param source Source for the.
1026 * @param complength The complength.
1027 * @param [in,out] dest If non-null, destination for the.
1028 * @param dstride The dstride.
1029 * @param dxor The dxor.
1030 *
1031 * @return An avhuff_error.
1032 */
1033
decode_video_lossless(int width,int height,const uint8_t * source,uint32_t complength,uint8_t * dest,uint32_t dstride,uint32_t dxor)1034 avhuff_error avhuff_decoder::decode_video_lossless(int width, int height, const uint8_t *source, uint32_t complength, uint8_t *dest, uint32_t dstride, uint32_t dxor)
1035 {
1036 // skip the first byte
1037 bitstream_in bitbuf(source, complength);
1038 bitbuf.read(8);
1039
1040 // import the tables
1041 huffman_error hufferr = m_ycontext.import_tree_rle(bitbuf);
1042 if (hufferr != HUFFERR_NONE)
1043 return AVHERR_INVALID_DATA;
1044 bitbuf.flush();
1045 hufferr = m_cbcontext.import_tree_rle(bitbuf);
1046 if (hufferr != HUFFERR_NONE)
1047 return AVHERR_INVALID_DATA;
1048 bitbuf.flush();
1049 hufferr = m_crcontext.import_tree_rle(bitbuf);
1050 if (hufferr != HUFFERR_NONE)
1051 return AVHERR_INVALID_DATA;
1052 bitbuf.flush();
1053
1054 // decode to the destination
1055 m_ycontext.reset();
1056 m_cbcontext.reset();
1057 m_crcontext.reset();
1058 for (uint32_t dy = 0; dy < height; dy++)
1059 {
1060 uint8_t *row = dest + dy * dstride;
1061 for (uint32_t dx = 0; dx < width / 2; dx++)
1062 {
1063 row[0 ^ dxor] = m_ycontext.decode_one(bitbuf);
1064 row[1 ^ dxor] = m_cbcontext.decode_one(bitbuf);
1065 row[2 ^ dxor] = m_ycontext.decode_one(bitbuf);
1066 row[3 ^ dxor] = m_crcontext.decode_one(bitbuf);
1067 row += 4;
1068 }
1069 m_ycontext.flush_rle();
1070 m_cbcontext.flush_rle();
1071 m_crcontext.flush_rle();
1072 }
1073
1074 // check for errors if we overflowed or decoded too little data
1075 if (bitbuf.overflow() || bitbuf.flush() != complength)
1076 return AVHERR_INVALID_DATA;
1077 return AVHERR_NONE;
1078 }
1079