Example #1
0
void BvcEncoder::encode_coef(int v, int active)
{
	int sign = v >> 7;
	v &= 0x7f;
	if ((v & ~active) != 0 || active == 0)
		abort();
	int n;
	for (n = 0; ((1 << n) & active) != 0; ++n)
		;
	PUT_BITS(v, n, nbb_, bb_, bs_);
	if (v != 0) {
		PUT_BITS(sign, 1, nbb_, bb_, bs_);
	}
}
Example #2
0
/*
 * "active" is of form 000...011...1
 */
int BvcEncoder::prune_layers(int active, int cm)
{
	if (active == 0)
		abort();

	int next;
	int n = 0;
	while (((next = active >> 1) & cm) == cm) {
		++n;
		active = next;
		if (active == 0)
			break;
	}
	if (active == 0) {
		PUT_BITS(0, n, nbb_, bb_, bs_);
	} else {
		PUT_BITS(1, n + 1, nbb_, bb_, bs_);
	}
	return (active);
}
Example #3
0
flush_bits (working_state *state)
{
  JOCTET _buffer[BUFSIZE], *buffer;
  size_t put_buffer;  int put_bits;
  size_t bytes, bytestocopy;  int localbuf = 0;

  put_buffer = state->cur.put_buffer;
  put_bits = state->cur.put_bits;
  LOAD_BUFFER()

  /* fill any partial byte with ones */
  PUT_BITS(0x7F, 7)
  while (put_bits >= 8) EMIT_BYTE()

  state->cur.put_buffer = 0;    /* and reset bit-buffer to empty */
  state->cur.put_bits = 0;
  STORE_BUFFER()

  return TRUE;
}
Example #4
0
/*XXX*/
int BvcEncoder::consume(const VideoFrame* vf)
{
	if (!samesize(vf))
		size(vf->width_, vf->height_);
	YuvFrame* p = (YuvFrame*)vf;
	tx_->flush();
	int layer = p->layer_;

	u_char* frm = (u_char*)p->bp_;
	const u_char* chm = frm + framesize_;
	blkno_ = -1;
	pktbuf* pb = getpkt(p->ts_, layer);
	const u_int8_t* crv = p->crvec_;
	memset(&b, 0, sizeof(b));

#ifdef SBC_STAT
	if (f[0] == 0) {
		f[0] = fopen("sbc0", "w");
		f[1] = fopen("sbc1", "w");
		f[2] = fopen("sbc2", "w");
		f[3] = fopen("sbc3", "w");
	}
#endif
	int cc = 0;
	int blkw = width_ >> 4;
	int blkh = height_ >> 4;
	int blkno = 0;
	for (int y = 0; y < blkh; ++y) {
		for (int x = 0; x < blkw; ++blkno, frm += 16, chm += 8,
		     ++x, ++crv) {
			int s = crv[0];
			if ((s & CR_SEND) == 0)
				continue;

#define MAXMBSIZE (16*16+2*8*8+4)
			if (bs_ + MAXMBSIZE >= es_) {
				cc += flush(pb, 0);
				pb = getpkt(p->ts_, layer);
			}

			int dblk = blkno - blkno_;
			blkno_ = blkno;
			if (dblk <= 0)
				abort();

			if (dblk == 1) {
				PUT_BITS(1, 1, nbb_, bb_, bs_);
b.mba += 1;
			} else if (dblk <= 17) {
				PUT_BITS(0x10 | (dblk - 2), 6, nbb_, bb_, bs_);
b.mba += 6;
			} else {
				PUT_BITS(dblk, 13, nbb_, bb_, bs_);
b.mba += 13;
			}
			/*
			 * Deal with boundaries of image.  This is
			 * simply ugly, but it's the price we have
			 * to pay for using a four tap filter stage.
			 * For the 1-3-3-1 filter set, we use symmetric
			 * extension at both analysis and synthesis
			 * to give perfect reconstruction.
			 * If we're at the top of the image, we simply
			 * copy the top row up (since the grabber's
			 * reserve one line of extra space).  Otherwise,
			 * we save pixels, do the symmetrization,
			 * encode the block, then restore the pixels.
			 */
			u_char ysave[16];
			u_char xsave[16];
			if (y == 0)
				memcpy(frm - width_, frm, 16);
			else if (y == blkh - 1) {
				u_char* p = frm + (width_ << 4);
				memcpy(ysave, p, 16);
				memcpy(p, p - width_, 16);
			}
			if (x == 0) {
				u_char* s = xsave;
				u_char* p = frm;
				for (int k = 0; k < 16; ++k) {
					*s++ = p[-1];
					p[-1] = p[0];
					p += width_;
				}
			} else if (x == blkw - 1) {
				u_char* s = xsave;
				u_char* p = frm + 16;
				for (int k = 0; k < 16; ++k) {
					*s++ = p[0];
					p[0] = p[-1];
					p += width_;
				}
			}
			encode_block(frm);
			encode_color(chm);
			encode_color(chm + (framesize_ >> 2));
			/*
			 * Now restore the pixels.  We don't bother
			 * with the "y = 0" case because the affected
			 * memory will not be used.
			 */
			if (y == blkh - 1) {
				u_char* p = frm + (width_ << 4);
				memcpy(p, ysave, 16);
			}
			if (x == 0) {
				u_char* s = xsave;
				u_char* p = frm;
				for (int k = 0; k < 16; ++k) {
					p[-1] = *s++;
					p += width_;
				}
			} else if (x == blkw - 1) {
				u_char* s = xsave;
				u_char* p = frm + 16;
				for (int k = 0; k < 16; ++k) {
					p[0] = *s++;
					p += width_;
				}
			}
		}
		frm += 15 * width_;
		chm += 7 * (width_ >> 1);
	}
#ifdef notdef
	double t = b.dc + b.mba;
	for (int i = 0; i < 4; ++i)
		t += b.zt[i] + b.sbc[i] + b.sbz[i];
	printf("dc\t%.3f\n", b.dc / t);
	printf("mba\t%.3f\n", b.mba / t);
	for (i = 0; i < 4; ++i) {
		printf("sbc%d\t%.3f (%.3f)\n", i, (b.sbc[i] + b.sbz[i]) / t,
		       b.sbz[i] / double(b.sbc[i] + b.sbz[i]));
		printf("zt%d\t%.3f\n", i, b.zt[i] / t);
	}
#endif
	cc += flush(pb, 1);
	return (cc);
}
Example #5
0
void BvcEncoder::encode_sbc(const u_int8_t* p)
{
#ifdef notyet
	u_int bb = bb_;
	int nbb = nbb_;
#endif
	u_char stack[3*64];
	u_char* sp = stack;
	u_char children[64];
	u_char grandchildren[64];
	
        smquant((u_int8_t*)p, qs_);
	find_children(p, children);
	find_grandchildren(children, grandchildren);

	/*XXX dpcm & entropy */
	PUT_BITS(p[0], 8, nbb_, bb_, bs_);
	b.dc += 8;

	int active = prune_layers(0x7f, children[0]);
	if (active == 0)
		return;
	int ga = prune_layers(active, grandchildren[0]);
	
	*sp++ = ga;
	*sp++ = active|0x80;
	*sp++ = 9;
	*sp++ = ga;
	*sp++ = active|0x80;
	*sp++ = 8;
	*sp++ = ga;
	*sp++ = active|0x80;
	*sp++ = 1;
	do {
		int k = *--sp;
		int active = *--sp;

		encode_coef(p[k], active & 0x7f);
		if (active & 0x80) {
			active = *--sp;
			if (active & 0x80)
				abort();
			if (active == 0)
				continue;
			active = prune_layers(active, children[k]);
			if (active == 0)
				continue;
			k = child[k];
			if (k < 64) {
				*sp++ = active;
				*sp++ = k + 9;
				*sp++ = active;
				*sp++ = k + 8;
				*sp++ = active;
				*sp++ = k + 1;
				*sp++ = active;
				*sp++ = k;
			} else {
#ifndef HAVE_HH
				if (k >= 192)
					k -= 156;
#endif
				encode_coef(p[k], active);
				encode_coef(p[k + 1], active);
				encode_coef(p[k + 8], active);
				encode_coef(p[k + 9], active);
			}
		} else {
			active = prune_layers(active, children[k]);
			if (active == 0)
				continue;
			int c = child[k];
			if (c < 64) {
				int ga = prune_layers(active, grandchildren[k]);
				k = c;
				*sp++ = ga;
				*sp++ = active|0x80;
				*sp++ = k + 9;
				*sp++ = ga;
				*sp++ = active|0x80;
				*sp++ = k + 8;
				*sp++ = ga;
				*sp++ = active|0x80;
				*sp++ = k + 1;
				*sp++ = ga;
				*sp++ = active|0x80;
				*sp++ = k;
			} else {
				k = c;
#ifndef HAVE_HH
				if (k >= 192)
					k -= 156;
#endif
				encode_coef(p[k], active);
				encode_coef(p[k + 1], active);
				encode_coef(p[k + 8], active);
				encode_coef(p[k + 9], active);
			}
		}

	} while (sp > stack);

#ifdef notyet
	bb_ = bb;
	nbb_ = nbb;
#endif
}
Example #6
0
/* 
 * get_segment grabs another record segment from the data stream.
 * fio->scc will be set as follows:
 *	SCCMIDL		fio->segbits = fio_cnt (all or rest of data in fio
 *			buffer) and no EOR was found
 *	SCCFULL		an EOR was found
 *
 * return values are as follows:
 *	2	encountered end of data -> stat will be set
 *	1	encountered end of file -> stat will be set
 *	0	segment (or part) is received -> stat will NOT be set
 *	ERR	encountered an error -> stat will be set
 */
static int
get_segment(struct fdinfo *fio, struct ffsw *stat)
	{
	long 	tword;
	int	left; 
	ssize_t	ret;

	unsigned char 	*cp;

	bitptr tbptr;

	struct text_f *text_info;

	text_info = (struct text_f *)fio->lyr_info;
	fio->lastscc = fio->scc;
/*
 *	If buffer is empty, or not enough to hold entire EOF marker,
 *	get more data.
 */
	if (fio->_cnt == 0 || fio->_cnt < text_info->eof_len)
		{
/*
 *		If num of bits not enough to hold EOF, move remainder
 *		to base of buffer and read in at base+remainder.  Adjust
 *		pointers and counts accordingly.
 */
		left = 0;
		if (fio->_cnt > 0)
			{
			bitptr tptr;

			left = fio->_cnt;
/*
 *			Move tail of data to the first word of the
 *			buffer (right justified).
 */
			GET_BITS(tword, fio->_ptr, left);
			SET_BPTR(tptr, fio->_base);
			PUT_BITS(tptr, tword, left);
			SET_BPTR(fio->_ptr, INC_BPTR(fio->_base, left));
			}
		else
			fio->_ptr = fio->_base;	/* reset _ptr */
		zero = 0;
		READBLK(ret, fio, (size_t)((uint64)fio->maxblksize >> 3), 
			stat, PARTIAL, &zero);
/*
 *		Add back in the 'extra' data
 */
		fio->_ptr = fio->_base;	/* reset _ptr */
		fio->_cnt = fio->_cnt + left;

		if (ret < (ssize_t)0)
			return(ERR);
		if (zero != 0)
			ERETURN(stat, FDC_ERR_UBC, 0);

		if (fio->_cnt == 0) /* must be at EOD */
			{
			return(setend(fio, stat));
			}
		}
Example #7
0
/*
 * Much of the compression algorithm used here is based very loosely on ideas
 * from isdn_lzscomp.c by Andre Beck: http://micky.ibh.de/~beck/stuff/lzs4i4l/
 */
int lzs_compress(unsigned char *dst, int dstlen, const unsigned char *src, int srclen)
{
    int length, offset;
    int inpos = 0, outpos = 0;
    uint16_t longest_match_len;
    uint16_t hofs, longest_match_ofs;
    uint16_t hash;
    uint32_t outbits = 0;
    int nr_outbits = 0;

    /*
     * This is theoretically a hash. But RAM is cheap and just loading the
     * 16-bit value and using it as a hash is *much* faster.
     */
#define HASH_BITS 16
#define HASH_TABLE_SIZE (1ULL << HASH_BITS)
#define HASH(p) (((struct oc_packed_uint16_t *)(p))->d)

    /*
     * There are two data structures for tracking the history. The first
     * is the true hash table, an array indexed by the hash value described
     * above. It yields the offset in the input buffer at which the given
     * hash was most recently seen. We use INVALID_OFS (0xffff) for none
     * since we know IP packets are limited to 64KiB and we can never be
     * *starting* a match at the penultimate byte of the packet.
     */
#define INVALID_OFS 0xffff
    uint16_t hash_table[HASH_TABLE_SIZE]; /* Buffer offset for first match */

    /*
     * The second data structure allows us to find the previous occurrences
     * of the same hash value. It is a ring buffer containing links only for
     * the latest MAX_HISTORY bytes of the input. The lookup for a given
     * offset will yield the previous offset at which the same data hash
     * value was found.
     */
#define MAX_HISTORY (1<<11) /* Highest offset LZS can represent is 11 bits */
    uint16_t hash_chain[MAX_HISTORY];

    /* Just in case anyone tries to use this in a more general-purpose
     * scenario... */
    if (srclen > INVALID_OFS + 1)
        return -EFBIG;

    /* No need to initialise hash_chain since we can only ever follow
     * links to it that have already been initialised. */
    memset(hash_table, 0xff, sizeof(hash_table));

    while (inpos < srclen - 2) {
        hash = HASH(src + inpos);
        hofs = hash_table[hash];

        hash_chain[inpos & (MAX_HISTORY - 1)] = hofs;
        hash_table[hash] = inpos;

        if (hofs == INVALID_OFS || hofs + MAX_HISTORY <= inpos) {
            PUT_BITS(9, src[inpos]);
            inpos++;
            continue;
        }

        /* Since the hash is 16-bits, we *know* the first two bytes match */
        longest_match_len = 2;
        longest_match_ofs = hofs;

        for (; hofs != INVALID_OFS && hofs + MAX_HISTORY > inpos;
                hofs = hash_chain[hofs & (MAX_HISTORY - 1)]) {

            /* We only get here if longest_match_len is >= 2. We need to find
               a match of longest_match_len + 1 for it to be interesting. */
            if (!memcmp(src + hofs + 2, src + inpos + 2, longest_match_len - 1)) {
                longest_match_ofs = hofs;

                do {
                    longest_match_len++;

                    /* If we cannot *have* a longer match because we're at the
                     * end of the input, stop looking */
                    if (longest_match_len + inpos == srclen)
                        goto got_match;

                } while (src[longest_match_len + inpos] == src[longest_match_len + hofs]);
            }

            /* Typical compressor tuning would have a break out of the loop
               here depending on the number of potential match locations we've
               tried, or a value of longest_match_len that's considered "good
               enough" so we stop looking for something better. We could also
               do a hybrid where we count the total bytes compared, so 5
               attempts to find a match better than 10 bytes is worth the same
               as 10 attempts to find a match better than 5 bytes. Or
               something. Anyway, we currently don't give up until we run out
               of reachable history — maximal compression. */
        }
got_match:
        /* Output offset, as 7-bit or 11-bit as appropriate */
        offset = inpos - longest_match_ofs;
        length = longest_match_len;

        if (offset < 0x80)
            PUT_BITS(9, 0x180 | offset);
        else
            PUT_BITS(13, 0x1000 | offset);

        /* Output length */
        if (length < 5)
            PUT_BITS(2, length - 2);
        else if (length < 8)
            PUT_BITS(4, length + 7);
        else {
            length += 7;
            while (length >= 30) {
                PUT_BITS(8, 0xff);
                length -= 30;
            }
            if (length >= 15)
                PUT_BITS(8, 0xf0 + length - 15);
            else
                PUT_BITS(4, length);
        }

        /* If we're already done, don't bother updating the hash tables. */
        if (inpos + longest_match_len >= srclen - 2) {
            inpos += longest_match_len;
            break;
        }

        /* We already added the first byte to the hash tables. Add the rest. */
        inpos++;
        while (--longest_match_len) {
            hash = HASH(src + inpos);
            hash_chain[inpos & (MAX_HISTORY - 1)] = hash_table[hash];
            hash_table[hash] = inpos++;
        }
    }

    /* Special cases at the end */
    if (inpos == srclen - 2) {
        hash = HASH(src + inpos);
        hofs = hash_table[hash];

        if (hofs != INVALID_OFS && hofs + MAX_HISTORY > inpos) {
            offset = inpos - hofs;

            if (offset < 0x80)
                PUT_BITS(9, 0x180 | offset);
            else
                PUT_BITS(13, 0x1000 | offset);

            /* The length is 2 bytes */
            PUT_BITS(2, 0);
        } else {
            PUT_BITS(9, src[inpos]);
            PUT_BITS(9, src[inpos + 1]);
        }
    } else if (inpos == srclen - 1) {
        PUT_BITS(9, src[inpos]);
    }

    /* End marker, with 7 trailing zero bits to ensure that it's flushed. */
    PUT_BITS(16, 0xc000);

    return outpos;
}
Example #8
0
encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
                  c_derived_tbl *dctbl, c_derived_tbl *actbl)
{
    int temp, temp2, temp3;
    int nbits;
    int r, code, size;
    JOCTET _buffer[BUFSIZE], *buffer;
    size_t put_buffer;
    int put_bits;
    int code_0xf0 = actbl->ehufco[0xf0], size_0xf0 = actbl->ehufsi[0xf0];
    size_t bytes, bytestocopy;
    int localbuf = 0;

    put_buffer = state->cur.put_buffer;
    put_bits = state->cur.put_bits;
    LOAD_BUFFER()

    /* Encode the DC coefficient difference per section F.1.2.1 */

    temp = temp2 = block[0] - last_dc_val;

    /* This is a well-known technique for obtaining the absolute value without a
     * branch.  It is derived from an assembly language technique presented in
     * "How to Optimize for the Pentium Processors", Copyright (c) 1996, 1997 by
     * Agner Fog.
     */
    temp3 = temp >> (CHAR_BIT * sizeof(int) - 1);
    temp ^= temp3;
    temp -= temp3;

    /* For a negative input, want temp2 = bitwise complement of abs(input) */
    /* This code assumes we are on a two's complement machine */
    temp2 += temp3;

    /* Find the number of bits needed for the magnitude of the coefficient */
    nbits = JPEG_NBITS(temp);

    /* Emit the Huffman-coded symbol for the number of bits */
    code = dctbl->ehufco[nbits];
    size = dctbl->ehufsi[nbits];
    PUT_BITS(code, size)
    CHECKBUF15()

    /* Mask off any extra bits in code */
    temp2 &= (((INT32) 1)<<nbits) - 1;

    /* Emit that number of bits of the value, if positive, */
    /* or the complement of its magnitude, if negative. */
    PUT_BITS(temp2, nbits)
    CHECKBUF15()

    /* Encode the AC coefficients per section F.1.2.2 */

    r = 0;                        /* r = run length of zeros */

    /* Manually unroll the k loop to eliminate the counter variable.  This
     * improves performance greatly on systems with a limited number of
     * registers (such as x86.)
     */
#define kloop(jpeg_natural_order_of_k) {  \
  if ((temp = block[jpeg_natural_order_of_k]) == 0) { \
    r++; \
  } else { \
    temp2 = temp; \
    /* Branch-less absolute value, bitwise complement, etc., same as above */ \
    temp3 = temp >> (CHAR_BIT * sizeof(int) - 1); \
    temp ^= temp3; \
    temp -= temp3; \
    temp2 += temp3; \
    nbits = JPEG_NBITS_NONZERO(temp); \
    /* if run length > 15, must emit special run-length-16 codes (0xF0) */ \
    while (r > 15) { \
      EMIT_BITS(code_0xf0, size_0xf0) \
      r -= 16; \
    } \
    /* Emit Huffman symbol for run length / number of bits */ \
    temp3 = (r << 4) + nbits;  \
    code = actbl->ehufco[temp3]; \
    size = actbl->ehufsi[temp3]; \
    EMIT_CODE(code, size) \
    r = 0;  \
  } \
}

    /* One iteration for each value in jpeg_natural_order[] */
    kloop(1);
    kloop(8);
    kloop(16);
    kloop(9);
    kloop(2);
    kloop(3);
    kloop(10);
    kloop(17);
    kloop(24);
    kloop(32);
    kloop(25);
    kloop(18);
    kloop(11);
    kloop(4);
    kloop(5);
    kloop(12);
    kloop(19);
    kloop(26);
    kloop(33);
    kloop(40);
    kloop(48);
    kloop(41);
    kloop(34);
    kloop(27);
    kloop(20);
    kloop(13);
    kloop(6);
    kloop(7);
    kloop(14);
    kloop(21);
    kloop(28);
    kloop(35);
    kloop(42);
    kloop(49);
    kloop(56);
    kloop(57);
    kloop(50);
    kloop(43);
    kloop(36);
    kloop(29);
    kloop(22);
    kloop(15);
    kloop(23);
    kloop(30);
    kloop(37);
    kloop(44);
    kloop(51);
    kloop(58);
    kloop(59);
    kloop(52);
    kloop(45);
    kloop(38);
    kloop(31);
    kloop(39);
    kloop(46);
    kloop(53);
    kloop(60);
    kloop(61);
    kloop(54);
    kloop(47);
    kloop(55);
    kloop(62);
    kloop(63);

    /* If the last coef(s) were zero, emit an end-of-block code */
    if (r > 0) {
        code = actbl->ehufco[0];
        size = actbl->ehufsi[0];
        EMIT_BITS(code, size)
    }