Esempio n. 1
0
i64 dbuf_getint_ext(dbuf *f, i64 pos, unsigned int nbytes,
	int is_le, int is_signed)
{
	if(is_signed) {
		// TODO: Extend this to any number of bytes, 1-8.
		switch(nbytes) {
		case 1: return (i64)(signed char)dbuf_getbyte(f, pos); break;
		case 2: return dbuf_geti16x(f, pos, is_le); break;
		case 4: return dbuf_geti32x(f, pos, is_le); break;
		case 8: return dbuf_geti64x(f, pos, is_le); break;
		default:
			return dbuf_getint_ext_x(f, pos, nbytes, is_le);
		}
	}
	else {
		switch(nbytes) {
		case 1: return (i64)dbuf_getbyte(f, pos); break;
		case 2: return dbuf_getu16x(f, pos, is_le); break;
		case 4: return dbuf_getu32x(f, pos, is_le); break;
		case 8: return dbuf_geti64x(f, pos, is_le); break;
		default:
			return dbuf_getuint_ext_x(f, pos, nbytes, is_le);
		}
	}
	return 0;
}
Esempio n. 2
0
// RLE algorithm occasionally called "RLE90". Variants of this are used by
// BinHex, ARC, StuffIt, and others.
int de_fmtutil_decompress_rle90(dbuf *inf, i64 pos1, i64 len,
	dbuf *outf, unsigned int has_maxlen, i64 max_out_len, unsigned int flags)
{
	i64 pos = pos1;
	u8 b;
	u8 lastbyte = 0x00;
	u8 countcode;
	i64 count;
	i64 nbytes_written = 0;

	while(pos < pos1+len) {
		if(has_maxlen && nbytes_written>=max_out_len) break;

		b = dbuf_getbyte(inf, pos);
		pos++;
		if(b!=0x90) {
			dbuf_writebyte(outf, b);
			nbytes_written++;
			lastbyte = b;
			continue;
		}

		// b = 0x90, which is a special code.
		countcode = dbuf_getbyte(inf, pos);
		pos++;

		if(countcode==0x00) {
			// Not RLE, just an escaped 0x90 byte.
			dbuf_writebyte(outf, 0x90);
			nbytes_written++;

			// Here there is an inconsistency between different RLE90
			// implementations.
			// Some of them can compress a run of 0x90 bytes, because the byte
			// to repeat is defined to be the "last byte emitted".
			// Others do not allow this. If the "0x90 0x00 0x90 0xNN" sequence
			// (with 0xNN>0) is encountered, they may (by accident?) repeat the
			// last non-0x90 byte emitted, or do something else.
			// Hopefully, valid files in such formats never contain this byte
			// sequence, so it shouldn't matter what we do here. But maybe not.
			// We might need to add an option to do something else.
			lastbyte = 0x90;
			continue;
		}

		// RLE. We already emitted one byte (because the byte to repeat
		// comes before the repeat count), so write countcode-1 bytes.
		count = (i64)(countcode-1);
		if(has_maxlen && (nbytes_written+count > max_out_len)) {
			count = max_out_len - nbytes_written;
		}
		dbuf_write_run(outf, lastbyte, count);
		nbytes_written += count;
	}

	return 1;
}
Esempio n. 3
0
// Caller allocates sdd. It does not need to be initialized.
// flags: 0x1 = Print a debug message if signature is found.
int de_fmtutil_detect_SAUCE(deark *c, dbuf *f, struct de_SAUCE_detection_data *sdd,
	unsigned int flags)
{
	de_zeromem(sdd, sizeof(struct de_SAUCE_detection_data));
	if(f->len<128) return 0;
	if(dbuf_memcmp(f, f->len-128, "SAUCE00", 7)) return 0;
	if(flags & 0x1) {
		de_dbg(c, "SAUCE metadata, signature at %"I64_FMT, f->len-128);
	}
	sdd->has_SAUCE = 1;
	sdd->data_type = dbuf_getbyte(f, f->len-128+94);
	sdd->file_type = dbuf_getbyte(f, f->len-128+95);
	return (int)sdd->has_SAUCE;
}
Esempio n. 4
0
static int read_dflen(deark *c, dbuf *f, de_int64 pos,
	de_int64 *dflen, de_int64 *bytes_consumed)
{
	de_int64 x;

	x = dbuf_getui16be(f, pos);
	if(x<32768) { // "Standard DataSet" format
		*dflen = x;
		*bytes_consumed = 2;
	}
	else { // "Extended DataSet" format
		de_int64 length_of_length;
		de_int64 i;

		length_of_length = x - 32768;
		*dflen = 0;
		*bytes_consumed = 2 + length_of_length;

		for(i=0; i<length_of_length; i++) {
			*dflen = ((*dflen)<<8) | dbuf_getbyte(f, pos+2+i);

			// IPTC seems to support fields up to (2^262136)-1 bytes.
			// We arbitrarily limit it (2^48)-1.
			if((*dflen)>=0x1000000000000LL) {
				de_err(c, "Bad or unsupported IPTC data field length\n");
				return 0;
			}
		}
	}

	return 1;
}
Esempio n. 5
0
u8 dbuf_getbyte_p(dbuf *f, i64 *ppos)
{
	u8 b;
	b = dbuf_getbyte(f, *ppos);
	(*ppos)++;
	return b;
}
Esempio n. 6
0
i64 dbuf_geti8(dbuf *f, i64 pos)
{
	u8 b;

	b = dbuf_getbyte(f, pos);
	return de_geti8_direct(&b);
}
Esempio n. 7
0
static void do_decode_24bit(deark *c, lctx *d, struct page_ctx *pg)
{
	dbuf *unc_pixels = NULL;
	struct deark_bitmap *img = NULL;
	de_int64 i, j;
	de_byte cr, cg, cb, ca;
	de_int64 w, h;
	de_int64 skip;

	w = pg->type_info->width;
	h = pg->type_info->height;

	// TODO: Try to support uncompressed 24-bit images, assuming they exist.

	// Apparently, some 'it32' icons begin with four extra 0x00 bytes.
	// Skip over the first four bytes if they are 0x00.
	// (I don't know the reason for these bytes, but this is the same
	// logic libicns uses.)
	skip = 0;
	if(pg->code4cc.id==0x69743332) { // 'it32' (128x128)
		if(!dbuf_memcmp(c->infile, pg->image_pos, "\0\0\0\0", 4)) {
			skip = 4;
		}
	}

	unc_pixels = dbuf_create_membuf(c, w*h*3, 1);
	do_uncompress_24(c, d, pg, unc_pixels, skip);

	img = de_bitmap_create(c, w, h, 4);

	for(j=0; j<pg->type_info->height; j++) {
		for(i=0; i<pg->type_info->width; i++) {
			cr = dbuf_getbyte(unc_pixels, j*w + i);
			cg = dbuf_getbyte(unc_pixels, (h+j)*w + i);
			cb = dbuf_getbyte(unc_pixels, (2*h+j)*w + i);
			if(pg->mask_pos)
				ca = de_getbyte(pg->mask_pos + j*w + i);
			else
				ca = 0xff;
			de_bitmap_setpixel_rgba(img, i, j, DE_MAKE_RGBA(cr,cg,cb,ca));
		}
	}

	de_bitmap_write_to_file(img, pg->filename_token, 0);
	de_bitmap_destroy(img);
	if(unc_pixels) dbuf_close(unc_pixels);
}
Esempio n. 8
0
// A 16-bit variant of de_fmtutil_uncompress_packbits().
int de_fmtutil_uncompress_packbits16(dbuf *f, i64 pos1, i64 len,
	dbuf *unc_pixels, i64 *cmpr_bytes_consumed)
{
	i64 pos;
	u8 b, b1, b2;
	i64 k;
	i64 count;
	i64 endpos;

	pos = pos1;
	endpos = pos1+len;

	while(1) {
		if(unc_pixels->has_len_limit && unc_pixels->len>=unc_pixels->len_limit) {
			break; // Decompressed the requested amount of dst data.
		}

		if(pos>=endpos) {
			break; // Reached the end of source data
		}
		b = dbuf_getbyte(f, pos++);

		if(b>128) { // A compressed run
			count = 257 - (i64)b;
			b1 = dbuf_getbyte(f, pos++);
			b2 = dbuf_getbyte(f, pos++);
			for(k=0; k<count; k++) {
				dbuf_writebyte(unc_pixels, b1);
				dbuf_writebyte(unc_pixels, b2);
			}
		}
		else if(b<128) { // An uncompressed run
			count = 1 + (i64)b;
			dbuf_copy(f, pos, count*2, unc_pixels);
			pos += count*2;
		}
		// Else b==128. No-op.
	}

	if(cmpr_bytes_consumed) *cmpr_bytes_consumed = pos - pos1;
	return 1;
}
Esempio n. 9
0
// Returns 0 on failure (currently impossible).
int de_fmtutil_uncompress_packbits(dbuf *f, i64 pos1, i64 len,
	dbuf *unc_pixels, i64 *cmpr_bytes_consumed)
{
	i64 pos;
	u8 b, b2;
	i64 count;
	i64 endpos;

	pos = pos1;
	endpos = pos1+len;

	while(1) {
		if(unc_pixels->has_len_limit && unc_pixels->len>=unc_pixels->len_limit) {
			break; // Decompressed the requested amount of dst data.
		}

		if(pos>=endpos) {
			break; // Reached the end of source data
		}
		b = dbuf_getbyte(f, pos++);

		if(b>128) { // A compressed run
			count = 257 - (i64)b;
			b2 = dbuf_getbyte(f, pos++);
			dbuf_write_run(unc_pixels, b2, count);
		}
		else if(b<128) { // An uncompressed run
			count = 1 + (i64)b;
			dbuf_copy(f, pos, count, unc_pixels);
			pos += count;
		}
		// Else b==128. No-op.
		// TODO: Some (but not most) ILBM specs say that code 128 is used to
		// mark the end of compressed data, so maybe there should be options to
		// tell us what to do when code 128 is encountered.
	}

	if(cmpr_bytes_consumed) *cmpr_bytes_consumed = pos - pos1;
	return 1;
}
Esempio n. 10
0
File: tga.c Progetto: jsummers/deark
static void do_decode_image_default(deark *c, lctx *d, struct tgaimginfo *imginfo, dbuf *unc_pixels,
	de_finfo *fi, unsigned int createflags)
{
	de_bitmap *img = NULL;
	i64 i, j;
	u8 b;
	u32 clr;
	u8 a;
	i64 rowspan;
	int output_bypp;
	unsigned int getrgbflags;
	i64 interleave_stride;
	i64 interleave_pass;
	i64 cur_rownum; // 0-based, does not account for bottom-up orientation

	if(d->pixel_depth==1) {
		de_warn(c, "1-bit TGA images are not portable, and may not be decoded correctly");
		rowspan = (imginfo->width+7)/8;
	}
	else {
		rowspan = imginfo->width*d->bytes_per_pixel;
	}

	if(d->color_type==TGA_CLRTYPE_GRAYSCALE || d->pixel_depth==1)
		output_bypp=1;
	else
		output_bypp=3;

	if(d->has_alpha_channel)
		output_bypp++;

	if(d->file_format==FMT_VST)
		getrgbflags = 0;
	else
		getrgbflags = DE_GETRGBFLAG_BGR;

	img = de_bitmap_create(c, imginfo->width, imginfo->height, output_bypp);

	switch(d->interleave_mode) {
	case 1: interleave_stride = 2; break;
	case 2: interleave_stride = 4; break;
	default: interleave_stride = 1;
	}

	cur_rownum = 0;
	interleave_pass = 0;

	for(j=0; j<imginfo->height; j++) {
		i64 j_adj;

		if(d->top_down)
			j_adj = cur_rownum;
		else
			j_adj = imginfo->height-1-cur_rownum;

		// Update the row number for next time
		cur_rownum += interleave_stride;
		if(cur_rownum >= imginfo->height) {
			// Went past the end of the image; move back to near the start.
			interleave_pass++;
			cur_rownum = interleave_pass;
		}

		for(i=0; i<imginfo->width; i++) {
			i64 i_adj;

			if(d->right_to_left)
				i_adj = imginfo->width-1-i;
			else
				i_adj = i;

			if(d->pixel_depth==1) {
				de_convert_row_bilevel(unc_pixels, j*rowspan, img, j_adj, 0);
			}
			else if(d->color_type==TGA_CLRTYPE_TRUECOLOR && (d->pixel_depth==15 || d->pixel_depth==16)) {
				clr = (u32)dbuf_getu16le(unc_pixels, j*rowspan + i*d->bytes_per_pixel);
				clr = de_rgb555_to_888(clr);
				de_bitmap_setpixel_rgb(img, i_adj, j_adj, clr);
			}
			else if(d->color_type==TGA_CLRTYPE_TRUECOLOR) {
				clr = dbuf_getRGB(unc_pixels, j*rowspan + i*d->bytes_per_pixel, getrgbflags);
				if(d->has_alpha_channel) {
					a = dbuf_getbyte(unc_pixels, j*rowspan + i*d->bytes_per_pixel+3);
					de_bitmap_setpixel_rgba(img, i_adj, j_adj, DE_SET_ALPHA(clr, a));
				}
				else {
					de_bitmap_setpixel_rgb(img, i_adj, j_adj, clr);
				}
			}
			else if(d->color_type==TGA_CLRTYPE_GRAYSCALE) {
				b = dbuf_getbyte(unc_pixels, j*rowspan + i*d->bytes_per_pixel);
				de_bitmap_setpixel_gray(img, i_adj, j_adj, b);
			}
			else if(d->color_type==TGA_CLRTYPE_PALETTE) {
				b = dbuf_getbyte(unc_pixels, j*rowspan + i*d->bytes_per_pixel);
				de_bitmap_setpixel_rgb(img, i_adj, j_adj, d->pal[(unsigned int)b]);
			}
		}
	}

	de_bitmap_write_to_file_finfo(img, fi, createflags);

	de_bitmap_destroy(img);
}
Esempio n. 11
0
// Read a "Variable Size Integer".
// Updates *pos.
// Returns:
//  0 on failure
//  1 on success
//  2 for a special "reserved" value
static int get_var_size_int(dbuf *f, i64 *val, i64 *pos,
	i64 nbytes_avail)
{
	i64 pos1;
	u8 b;
	u8 mask;
	unsigned int k;
	int retval = 0;
	u8 test_bit;
	unsigned int initial_zero_bits;

	pos1 = *pos;
	if(nbytes_avail<1) goto done;

	// This is an unsigned int. In a i64, we can support up to 63
	// bits.
	// For now we'll hope that 8 octets is the most we'll have to support,
	// but it's possible we'll have to support 9 or even more, which will
	// require additional logic.
	//
	//  1xxxxxxx width_nbits=0, octets=1, data_bits=7
	//  01xxxxxx width_nbits=1, octets=2, data_bits=14
	//  ...
	//  00000001 width_nbits=7, octets=8, data_bits=56
	//  00000000 1xxxxxxx width_nbits=8, octets=9, data_bits=63

	b = dbuf_getbyte(f, *pos);
	(*pos)++;

	test_bit = 0x80;
	initial_zero_bits = 0;
	while(1) {
		if(b>=test_bit) {
			break;
		}

		// "Not it". Try the next-larger number of initial 0 bits.
		initial_zero_bits++;
		test_bit >>= 1;
		if(test_bit==0) {
			goto done;
		}
	}

	mask = 0x7f >> initial_zero_bits;

	*val = (i64)(b & mask);

	// Read remaining bytes, if any.
	for(k=0; k<initial_zero_bits; k++) {
		if(*pos >= pos1+nbytes_avail) goto done;
		b = dbuf_getbyte(f, *pos);
		(*pos)++;
		if(*val > 0x07ffffffffffffffLL) {
			goto done;
		}
		*val = ((*val)<<8) | ((i64)b);
	}

	if(initial_zero_bits==0 && (*val)==0x7f) {
		// TODO: Fully handle "reserved" element value of all 1 bits.
		retval = 2;
		goto done;
	}

	retval = 1;

done:
	if(retval!=1) {
		*val = 0;
	}
	return retval;
}