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