Exemple #1
0
/*
 * Helper routine to bridge to packJPG C++ lib, without changing packJPG itself.
 */
size_t
packjpg_filter_process(uchar_t *in_buf, size_t len, uchar_t **out_buf)
{
	unsigned int len1;
	uchar_t *pos;

	/*
	 * Workaround for packJPG limitation, not a bug per se. Images created with
	 * Polaroid cameras appear to have some weird huffman data in the middle which
	 * appears not to be interpreted by any image viewer/editor. This data gets
	 * stripped by packJPG.
	 * So the restored images will be visually correct, but, will be smaller than the
	 * original. So we need to look at the Exif Manufacturer tag for 'Polaroid' and
	 * skip those images. This should be within the first 512 bytes of the
	 * file (really...?) so we do a simple buffer scan without trying to parse Exif
	 * data.
	 */
	pos = (uchar_t *)memchr(in_buf, 'P', 512);
	while (pos) {
		if (LE64(U64_P(pos)) == POLAROID_LE)
			return (0);
		pos++;
		pos = (uchar_t *)memchr(pos, 'P', 512);
	}
	pjglib_init_streams(in_buf, 1, len, *out_buf, 1);
	len1 = len;
	if (!pjglib_convert_stream2mem(out_buf, &len1, NULL))
		return (0);
	if (len1 == len)
		return (0);
	return (len1);
}
Exemple #2
0
int
zero_rle_encode(const void *ibuf, const unsigned int ilen,
	void *obuf, unsigned int *olen)
{
	unsigned int pos1, pos2, sz;
	unsigned short count;
	const uchar_t *ib = (const uchar_t *)ibuf;
	uchar_t *ob = (uchar_t *)obuf;
	uint64_t val;

	sz = sizeof (val) - 1;
	pos2 = 0;
	for (pos1=0; pos1<ilen && pos2<*olen;) {
		count = 0;
		if (ib[pos1] == 0) {
			/*
			 * We have a run of zeroes. Count them and store only the count.
			 */
			while (pos1 < (ilen - sz) && count < (COUNT_MAX - sz)) {
				val = U64_P(ib+pos1);
				if (val) break;
				pos1 += sizeof (val); count += sizeof (val);
			}
			for (;pos1<ilen && ib[pos1]==0 && count<COUNT_MAX; pos1++) ++count;
			count |= ZERO_MASK;
			U16_P(ob + pos2) = htons(count);
			pos2 += 2;
			if (pos2 > *olen) break;
		} else {
			unsigned int pos3, pos4, state;
			pos3 = pos2;
			pos2 += 2;
			if (pos2 > *olen) break;

			state = 0;
			for (;pos1<ilen && pos2<*olen && count<COUNT_MAX;) {
				if (ib[pos1] != 0) state = 0;
				if (ib[pos1] == 0 && !state) {
					state = 1;
					// Lookahead if there are at least 4 consecutive zeroes
					if (ilen > 3) {
						pos4 = *((unsigned int *)(ib+pos1));
						if (!pos4) break;
					}
				}
				ob[pos2++] = ib[pos1++];
				++count;
			}
			U16_P(ob + pos3) = htons(count);
		}
	}
	*olen = pos2;
	if (pos1 < ilen) {
		return (-1);
	} else {
		return (0);
	}
}