static int dec_readmarker(struct in *in)
{
	int m;

	in->left = fillbits(in, in->left, in->bits);
	if ((m = in->marker) == 0)
		return 0;
	in->left = 0;
	in->marker = 0;
	return m;
}
Example #2
0
bool AMPDecoder::L3_DecodeFrame() {
	int gr, ch, sb, ss;

	profile_set(0);

	// bring in new bits

	fillbits(frame_size);

	// rewind read point back to beginning of data for this frame

//_RPT2(0,"Layer III: added %ld bytes, rewind to %ld\n", frame_size, sideinfo.main_data_begin + frame_size);

	rewind(sideinfo.main_data_begin + frame_size);

	profile_add(p_header);

	// process granules.
	//
	// 2 for MPEG-1, 1 for MPEG-2

	for (gr=0;gr<(is_mpeg2 ? 1 : 2);gr++) {
		float lr[2][SBLIMIT][SSLIMIT],ro[SBLIMIT][SSLIMIT];
		III_scalefac_t scalefac;
		int sample_end[2];
		int new_end;

		// process each channel in the granule.
		
		for (ch=0; ch<channels; ch++) {
			long int is[SBLIMIT*SSLIMIT];   /* Quantized samples. */
			int part2_start;
			part2_start = tellbits();
			int limit;

			// decode scale factors

			if (is_mpeg2)
				L3_GetScaleFactors2(&scalefac, ch);
			else
				L3_GetScaleFactors1(&scalefac, gr, ch);

			profile_add(p_scalefac);

			// decode samples

			limit = L3_HuffmanDecode(is, ch, gr, part2_start);

			profile_add(p_huffdec);

			// dequantize samples

			sample_end[ch] = L3_DequantizeSample(is, (float *)lr[ch], &scalefac[ch],
				&sideinfo.ch[ch].gr[gr], ch, limit);

			profile_add(p_dequan);
		}

		// process joint stereo in lr

		new_end = L3_Stereo((float (*)[576])lr, &scalefac, &sideinfo.ch[0].gr[gr], sample_end[0], sample_end[1]);

		if (new_end > 0)
			sample_end[0] = sample_end[1] = new_end;

		profile_add(p_stereo);

		float polyPhaseIn[2][SSLIMIT][SBLIMIT];
			
		for (ch=0; ch<channels; ch++) {
			
			// reorder samples; use 'hybridOut' as our out here, to reuse memory

			L3_Reorder((float *)lr[ch],(float *)ro,&sideinfo.ch[ch].gr[gr]);

			// antialiasing

			L3_Antialias(lr[ch], /* Antialias butterflies. */
				&sideinfo.ch[ch].gr[gr]);

			profile_add(p_antialias);

			// Hybrid synthesis.

			L3_Hybrid(lr[ch], polyPhaseIn[ch], ch, &sideinfo.ch[ch].gr[gr], sample_end[ch]);

			profile_add(p_hybrid);
		}

		if (mode == MODE_MONO)
			for(ss=0; ss<18; ss++)
				polyphase(polyPhaseIn[0][ss], NULL, psDest + 32*ss + 576*gr, !!(ss&1));
		else
			for(ss=0; ss<18; ss++)
				polyphase(polyPhaseIn[0][ss], polyPhaseIn[1][ss], psDest + 64*ss + 1152*gr, !!(ss&1));

		profile_add(p_polyphase2);
	}

#ifdef RDTSC_PROFILE

	if (!(++p_frames & 127)) {
		static char buf[256];

		sprintf(buf, "%d frames: total %I64d, header %d%%, scalefac %d%%, huffdec %d%%, dequan %d%%, stereo %d%%, antialias %d%%, hybrid %d%%, poly %d%%/%d%%\n"
				,p_frames
				,p_total
				,(long)((p_header*100)/p_total)
				,(long)((p_scalefac*100)/p_total)
				,(long)((p_huffdec*100)/p_total)
				,(long)((p_dequan*100)/p_total)
				,(long)((p_stereo*100)/p_total)
				,(long)((p_antialias*100)/p_total)
				,(long)((p_hybrid*100)/p_total)
				,(long)((p_polyphase1*100)/p_total)
				,(long)((p_polyphase2*100)/p_total)
				);
		OutputDebugString(buf);
	}
#endif

	// set sample count

	lSampleCount = 1152;
	if (is_mpeg2)
		lSampleCount = 576;

	if (channels>1)
		lSampleCount <<=1;

//	_RPT2(0,"Layer III: terminated with %ld bits left (%ld bytes)\n", tellbits(), tellbits()/8);
			 
	return true;
}
fz_error
fz_processlzwd(fz_filter *filter, fz_buffer *in, fz_buffer *out)
{
	fz_lzwd *lzw = (fz_lzwd*)filter;
	unsigned char *s;
	int len;

	if (lzw->resume)
	{
		lzw->resume = 0;
		goto output;
	}

	while (1)
	{
		if (fillbits(lzw, in))
		{
			if (in->eof)
			{
				if (lzw->bidx > 32 - lzw->codebits)
				{
					unstuff(lzw, in);
					return fz_iodone;
				}
			}
			else
			{
				return fz_ioneedin;
			}
		}

		lzw->code = lzw->word >> (32 - lzw->codebits);

		if (lzw->code == LZW_EOD)
		{
			eatbits(lzw, lzw->codebits);
			unstuff(lzw, in);
			return fz_iodone;
		}

		if (lzw->code == LZW_CLEAR)
		{
			int oldcodebits = lzw->codebits;

			lzw->codebits = MINBITS;
			lzw->nextcode = LZW_FIRST;

			lzw->code = lzw->word >> (32 - oldcodebits - MINBITS) & ((1 << MINBITS) - 1);

			if (lzw->code == LZW_EOD)
			{
				eatbits(lzw, oldcodebits + MINBITS);
				unstuff(lzw, in);
				return fz_iodone;
			}

			eatbits(lzw, oldcodebits + MINBITS);

			lzw->oldcode = lzw->code;

			if (out->wp + 1 > out->ep)
			{
				lzw->resume = 1;
				return fz_ioneedout;
			}

			*out->wp++ = lzw->code;

			continue;
		}

		eatbits(lzw, lzw->codebits);

		/* if stream starts without a clear code, oldcode is undefined... */
		if (lzw->oldcode == -1)
		{
			lzw->oldcode = lzw->code;
			goto output;
		}

		/* add new entry to the code table */
		lzw->table[lzw->nextcode].prev = lzw->oldcode;
		lzw->table[lzw->nextcode].firstchar = lzw->table[lzw->oldcode].firstchar;
		lzw->table[lzw->nextcode].length = lzw->table[lzw->oldcode].length + 1;
		if (lzw->code < lzw->nextcode)
			lzw->table[lzw->nextcode].value = lzw->table[lzw->code].firstchar;
		else
			lzw->table[lzw->nextcode].value = lzw->table[lzw->nextcode].firstchar;

		lzw->nextcode ++;

		if (lzw->nextcode >= (1 << lzw->codebits) - lzw->earlychange - 1)
		{
			lzw->codebits ++;
			if (lzw->codebits > MAXBITS)
				lzw->codebits = MAXBITS;	/* FIXME */
		}

		lzw->oldcode = lzw->code;

output:
		/* code maps to a string, copy to output (in reverse...) */
		if (lzw->code > 255)
		{
			if (out->wp + lzw->table[lzw->code].length > out->ep)
			{
				lzw->resume = 1;
				return fz_ioneedout;
			}

			len = lzw->table[lzw->code].length;
			s = out->wp + len;

			do
			{
				*(--s) = lzw->table[lzw->code].value;
				lzw->code = lzw->table[lzw->code].prev;
			} while (lzw->code >= 0 && s > out->wp);
			out->wp += len;
		}

		/* ... or just a single character */
		else
		{
			if (out->wp + 1 > out->ep)
			{
				lzw->resume = 1;
				return fz_ioneedout;
			}

			*out->wp++ = lzw->code;
		}
	}
Example #4
0
void AMPDecoder::L3_PrereadFrame() {
	fillbits(frame_size);
}
Example #5
0
static int
readlzwd(fz_stream *stm, unsigned char *buf, int len)
{
	fz_lzwd *lzw = stm->state;
	unsigned char *p = buf;
	unsigned char *ep = buf + len;
	unsigned char *s;
	int codelen;

	while (lzw->rp < lzw->wp && p < ep)
		*p++ = *lzw->rp++;

	while (p < ep)
	{
		if (lzw->eod)
			return 0;

		if (fillbits(lzw))
		{
			if (lzw->bidx > 32 - lzw->codebits)
			{
				lzw->eod = 1;
				return p - buf;
			}
		}

		lzw->code = lzw->word >> (32 - lzw->codebits);
		lzw->code &= (1 << lzw->codebits) - 1;
		eatbits(lzw, lzw->codebits);

		if (lzw->code == LZW_EOD)
		{
			lzw->eod = 1;
			return p - buf;
		}

		if (lzw->code == LZW_CLEAR)
		{
			lzw->codebits = MINBITS;
			lzw->nextcode = LZW_FIRST;
			lzw->oldcode = -1;
			continue;
		}

		/* if stream starts without a clear code, oldcode is undefined... */
		if (lzw->oldcode == -1)
		{
			lzw->oldcode = lzw->code;
			goto output;
		}

		/* add new entry to the code table */
		lzw->table[lzw->nextcode].prev = lzw->oldcode;
		lzw->table[lzw->nextcode].firstchar = lzw->table[lzw->oldcode].firstchar;
		lzw->table[lzw->nextcode].length = lzw->table[lzw->oldcode].length + 1;
		if (lzw->code < lzw->nextcode)
			lzw->table[lzw->nextcode].value = lzw->table[lzw->code].firstchar;
		else if (lzw->code == lzw->nextcode)
			lzw->table[lzw->nextcode].value = lzw->table[lzw->nextcode].firstchar;
		else
			fz_warn("out of range code encountered in lzw decode");

		lzw->nextcode ++;

		if (lzw->nextcode > (1 << lzw->codebits) - lzw->earlychange - 1)
		{
			lzw->codebits ++;
			if (lzw->codebits > MAXBITS)
				lzw->codebits = MAXBITS;	/* FIXME */
		}

		lzw->oldcode = lzw->code;

output:

		/* code maps to a string, copy to output (in reverse...) */
		if (lzw->code > 255)
		{
			codelen = lzw->table[lzw->code].length;
			lzw->rp = lzw->bp;
			lzw->wp = lzw->bp + codelen;

			assert(codelen < MAXLENGTH);

			s = lzw->wp;
			do {
				*(--s) = lzw->table[lzw->code].value;
				lzw->code = lzw->table[lzw->code].prev;
			} while (lzw->code >= 0 && s > lzw->bp);
		}

		/* ... or just a single character */
		else
		{
			lzw->bp[0] = lzw->code;
			lzw->rp = lzw->bp;
			lzw->wp = lzw->bp + 1;
		}

		/* copy to output */
		while (lzw->rp < lzw->wp && p < ep)
			*p++ = *lzw->rp++;
	}

	return p - buf;
}