Esempio n. 1
0
static void do_glyphs(deark *c, lctx *d)
{
	struct de_bitmap_font *font = NULL;
	de_byte *font_data = NULL;
	de_int64 i;
	de_int64 glyph_rowspan;

	font = de_create_bitmap_font(c);
	font->has_nonunicode_codepoints = 1;
	font->nominal_width = (int)d->glyph_width;
	font->nominal_height = (int)d->glyph_height;
	font->num_chars = d->num_glyphs; // This may increase later
	glyph_rowspan = (d->glyph_width+7)/8;

	d->num_chars_alloc = d->num_glyphs;
	if(d->read_extra_codepoints)
		d->num_chars_alloc += MAX_EXTRA_CODEPOINTS;

	d->index_of_first_extra_codepoint = d->num_glyphs;
	d->num_extra_codepoints = 0;

	font->char_array = de_malloc(c, d->num_chars_alloc * sizeof(struct de_bitmap_font_char));

	font_data = de_malloc(c, d->font_data_size);
	de_read(font_data, d->headersize, d->font_data_size);

	for(i=0; i<d->num_chars_alloc; i++) {
		font->char_array[i].width = font->nominal_width;
		font->char_array[i].height = font->nominal_height;
		font->char_array[i].rowspan = glyph_rowspan;
		if(i<d->num_glyphs)
			font->char_array[i].codepoint_nonunicode = (de_int32)i;
		else
			font->char_array[i].codepoint_nonunicode = DE_INVALID_CODEPOINT;
		font->char_array[i].codepoint_unicode = DE_INVALID_CODEPOINT;
		if(i<d->num_glyphs)
			font->char_array[i].bitmap = &font_data[i*d->bytes_per_glyph];
	}

	if(d->has_unicode_table) {
		if(d->version==2)
			do_psf2_unicode_table(c, d, font);
		else
			do_psf1_unicode_table(c, d, font);
	}

	if(d->num_extra_codepoints>0) {
		font->num_chars = d->index_of_first_extra_codepoint + d->num_extra_codepoints;
		de_dbg(c, "codepoints aliases: %d\n", (int)d->num_extra_codepoints);
		de_dbg(c, "total characters: %d\n", (int)font->num_chars);
	}

	de_font_bitmap_font_to_image(c, font, NULL, 0);

	if(font) {
		de_free(c, font->char_array);
		de_destroy_bitmap_font(c, font);
	}
	de_free(c, font_data);
}
Esempio n. 2
0
File: tga.c Progetto: jsummers/deark
static int do_decode_rle(deark *c, lctx *d, i64 pos1, dbuf *unc_pixels)
{
	u8 b;
	i64 count;
	i64 k;
	u8 buf[8];
	i64 pos = pos1;

	while(1) {
		if(pos >= c->infile->len) break;
		if(unc_pixels->len >= d->main_image.img_size_in_bytes) break;

		b = de_getbyte(pos);
		pos++;

		if(b & 0x80) { // RLE block
			count = (i64)(b - 0x80) + 1;
			de_read(buf, pos, d->bytes_per_pixel);
			pos += d->bytes_per_pixel;
			for(k=0; k<count; k++) {
				dbuf_write(unc_pixels, buf, d->bytes_per_pixel);
			}
		}
		else { // uncompressed block
			count = (i64)(b) + 1;
			dbuf_copy(c->infile, pos, count * d->bytes_per_pixel, unc_pixels);
			pos += count * d->bytes_per_pixel;
		}
	}

	de_dbg(c, "decompressed %d bytes to %d bytes", (int)(pos-pos1), (int)unc_pixels->len);
	return 1;
}
Esempio n. 3
0
static void do_extract_png_or_jp2(deark *c, lctx *d, struct page_ctx *pg)
{
	de_byte buf[8];
	de_finfo *fi = NULL;

	de_dbg(c, "Trying to extract file at %d\n", (int)pg->image_pos);

	// Detect the format
	de_read(buf, pg->image_pos, sizeof(buf));

	fi = de_finfo_create(c);
	de_finfo_set_name_from_sz(c, fi, pg->filename_token, DE_ENCODING_ASCII);

	if(buf[4]=='j' && buf[5]=='P') {
		dbuf_create_file_from_slice(c->infile, pg->image_pos, pg->image_len, "jp2", fi, 0);
	}
	else if(buf[0]==0x89 && buf[1]==0x50) {
		dbuf_create_file_from_slice(c->infile, pg->image_pos, pg->image_len, "png", fi, 0);
	}
	else {
		de_err(c, "(Image #%d) Unidentified file format\n", pg->image_num);
	}

	de_finfo_destroy(c, fi);
}
Esempio n. 4
0
File: png.c Progetto: jsummers/deark
static int do_identify_png_internal(deark *c)
{
	u8 buf[8];
	de_read(buf, 0, sizeof(buf));
	if(!de_memcmp(buf, "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8)) return DE_PNGFMT_PNG;
	if(!de_memcmp(buf, "\x8b\x4a\x4e\x47\x0d\x0a\x1a\x0a", 8)) return DE_PNGFMT_JNG;
	if(!de_memcmp(buf, "\x8a\x4d\x4e\x47\x0d\x0a\x1a\x0a", 8)) return DE_PNGFMT_MNG;
	return 0;
}
Esempio n. 5
0
static int de_identify_cardfile(deark *c)
{
	de_byte buf[4];
	de_read(buf, 0, 4);

	if(!de_memcmp(buf, "MGC", 3)) return 80;
	if(!de_memcmp(buf, "RRG", 3)) return 80;
	return 0;
}
Esempio n. 6
0
static int de_identify_psionapp(deark *c)
{
	de_byte b[16];
	de_read(b, 0, 16);
	if(!de_memcmp(b, "ImageFileType**\0", 16))
		return 100;
	if(!de_memcmp(b, "OPLObjectFile**\0", 16))
		return 100;
	return 0;
}
Esempio n. 7
0
static int de_identify_gzip(deark *c)
{
	u8 buf[3];

	de_read(buf, 0, 3);
	if(buf[0]==0x1f && buf[1]==0x8b) {
		if(buf[2]==0x08) return 100;
		return 10;
	}
	return 0;
}
Esempio n. 8
0
static int identify_fmt(deark *c, de_int64 pos)
{
	de_byte buf[3];

	de_read(buf, pos, 3);
	if(buf[0]!='P') return 0;

	if(buf[1]=='7' && buf[2]==0x0a)
		return FMT_PAM;
	if(buf[1]>='1' && buf[1]<='6')
		return buf[1] - '0';
	return 0;
}
Esempio n. 9
0
File: rpm.c Progetto: jsummers/deark
static void read_compression_type(deark *c, lctx *d, i64 pos)
{
	u8 buf[16];

	de_dbg(c, "compression type at %d", (int)pos);

	de_read(buf, pos, sizeof(buf));

	if(!de_memcmp(buf, "lzma\0", 5)) {
		d->cmpr_type = DE_RPM_CMPR_LZMA;
	}
	// Other valid compression types are "gzip", "bzip2", and "xz".
	// We'll autodetect most of them, but lzma is hard to detect.
}
Esempio n. 10
0
File: tga.c Progetto: jsummers/deark
static int de_identify_tga(deark *c)
{
	u8 b[18];
	u8 x;
	int has_tga_ext;

	if(has_signature(c)) {
		return 100;
	}

	// TGA v1 format has no signature, but there are only a few common types of
	// it. We'll at least try to identify anything that we support.
	de_read(b, 0, 18);

	if(b[1]>1) return 0; // Color map type should be 0 or 1.

	// bits/pixel:
	if(b[16]!=1 && b[16]!=8 && b[16]!=15 && b[16]!=16 && b[16]!=24 && b[16]!=32) return 0;

	if(b[2]!=0 && b[2]!=1 && b[2]!=2 && b[2]!=3 &&
		b[2]!=9 && b[2]!=10 && b[2]!=11 && b[2]!=32 && b[2]!=33)
	{
		return 0; // Unknown image type
	}

	if(b[12]==0 && b[13]==0) return 0; // Width can't be 0.
	if(b[14]==0 && b[15]==0) return 0; // Height can't be 0.

	// Bits per palette entry. Supposed to be 0 if there is no palette, but
	// in practice it may be 24 instead.
	if((b[1]==0 && b[7]==0) || b[7]==15 || b[7]==16 || b[7]==24 || b[7]==32) {
		;
	}
	else {
		return 0;
	}

	has_tga_ext = de_input_file_has_ext(c, "tga");

	x = b[17]&0x0f; // Number of attribute bits
	if(x!=0 && x!=1 && x!=8 && !has_tga_ext) return 0;

	if(has_tga_ext) {
		return 100;
	}
	if(de_input_file_has_ext(c, "vst")) {
		return 40;
	}
	return 8;
}
Esempio n. 11
0
File: wri.c Progetto: jsummers/deark
static int de_identify_wri(deark *c)
{
	u8 buf[6];
	de_read(buf, 0, 6);

	if((buf[0]==0x31 || buf[0]==0x32) &&
		!de_memcmp(&buf[1], "\xbe\x00\x00\x00\xab", 5))
	{
		i64 pnMac;
		pnMac = de_getu16le(48*2);
		if(pnMac==0) return 0; // Apparently MSWord, not Write
		return 100;
	}
	return 0;
}
Esempio n. 12
0
static int de_identify_macpaint(deark *c)
{
	de_byte buf[8];

	de_read(buf, 65, 8);

	// Not all MacPaint files can be easily identified, but this will work
	// for some of them.
	if(!de_memcmp(buf, "PNTGMPNT", 8)) return 80;
	if(!de_memcmp(buf, "PNTG", 4)) return 70;

	if(de_input_file_has_ext(c, "mac")) return 10;
	if(de_input_file_has_ext(c, "macp")) return 15;
	if(de_input_file_has_ext(c, "pntg")) return 15;
	return 0;
}
Esempio n. 13
0
File: wri.c Progetto: jsummers/deark
static void wri_convert_image_pal4planar(deark *c, i64 fpos,
	i64 bytes_per_row_per_plane, de_bitmap *img)
{
	const i64 nplanes = 4;
	i64 i, j, plane;
	i64 rowspan;
	u8 *rowbuf = NULL;
	static const u32 pal16[16] = {
		0x000000,0x800000,0x008000,0x808000,0x000080,0x800080,0x008080,0x808080,
		0xc0c0c0,0xff0000,0x00ff00,0xffff00,0x0000ff,0xff00ff,0x00ffff,0xffffff
	};

	rowspan = bytes_per_row_per_plane * nplanes;
	rowbuf = de_malloc(c, rowspan);

	// The usual order seems to be
	//  row0_plane0x1, row0_plane0x2, row0_plane0x4, row0_plane0x8,
	//  row1_plane0x1, row1_plane0x2, row1_plane0x4, row1_plane0x8,
	//  ...
	// But I have seen another, and I see no way to detect/support it.

	for(j=0; j<img->height; j++) {
		de_read(rowbuf, fpos+j*rowspan, rowspan);

		for(i=0; i<img->width; i++) {
			unsigned int palent = 0;
			u32 clr;

			for(plane=0; plane<nplanes; plane++) {
				unsigned int n = 0;
				i64 idx;

				idx = bytes_per_row_per_plane*plane + i/8;
				if(idx<rowspan) n = rowbuf[idx];
				if(n & (1<<(7-i%8))) {
					palent |= (1<<plane);
				}
			}

			clr = DE_MAKE_OPAQUE(pal16[palent]);
			de_bitmap_setpixel_rgb(img, i, j, clr);
		}
	}

	de_free(c, rowbuf);
}
Esempio n. 14
0
static void handle_embedded_file(deark *c, lctx *d, de_int64 offset, de_int64 len)
{
	de_byte buf[16];
	const char *ext;
	int extract_this_file;
	int is_pic;

	de_dbg(c, "embedded file at %d, len=%d\n", (int)offset, (int)len);
	is_pic = 0;
	ext = "bin";
	extract_this_file = 0;

	if(len>0 && c->extract_level>=2)
		extract_this_file = 1;

	// As far as I can tell, there's no way to tell the type of an
	// embedded file, except by sniffing it.
	de_read(buf, offset, 16);
	if(len>=8) {
		if(!de_memcmp(buf, "PIC\xdc\x30\x30", 6)) {
			// Looks like a PIC file
			is_pic = 1;
			ext = "pic";
			extract_this_file = 1;
		}
	}

	if(extract_this_file) {
		if(is_pic && d->convert_images) {
			// Convert PIC to PNG.
			// For consistency, this option shouldn't exist. But I'm not sure that
			// PIC files embedded in APP files are really the same as PIC files on
			// their own. They might need special handling. Until I'm sure they don't,
			// I'll leave this option here.
			de_run_module_by_id_on_slice(c, "psionpic", NULL, c->infile, offset, len);
		}
		else {
			// Just extract the file
			dbuf_create_file_from_slice(c->infile, offset, len, ext, NULL, is_pic?0:DE_CREATEFLAG_IS_AUX);
		}
	}
	else {
		de_dbg(c, "(not extracting this file)\n");
	}
}
Esempio n. 15
0
File: ogg.c Progetto: jsummers/deark
static void do_identify_bitstream(deark *c, lctx *d, struct stream_info *si, i64 pos, i64 len)
{
	u8 idbuf[16];
	size_t bytes_to_scan;
	size_t k;

	bytes_to_scan = (size_t)len;
	if(bytes_to_scan > sizeof(idbuf)) {
		bytes_to_scan = sizeof(idbuf);
	}

	de_read(idbuf, pos, bytes_to_scan);

	for(k=0; k<DE_ITEMS_IN_ARRAY(stream_type_info_arr); k++) {
		if(!de_memcmp(idbuf, stream_type_info_arr[k].magic,
			stream_type_info_arr[k].magic_len))
		{
			si->sti = &stream_type_info_arr[k];
			si->stream_type = si->sti->stream_type;
			break;
		}
	}

	if(si->stream_type==STREAMTYPE_VORBIS) {
		d->found_vorbis = 1;
	}
	else if(si->stream_type==STREAMTYPE_THEORA) {
		d->found_theora = 1;
	}
	else if(si->stream_type==STREAMTYPE_SKELETON) {
		d->found_skeleton = 1;
	}
	else if(si->sti && (si->sti->flags&0x1)) {
		d->found_ogm = 1;
	}

	if(si->stream_type!=STREAMTYPE_VORBIS && si->stream_type!=STREAMTYPE_THEORA) {
		d->has_non_vorbis_non_theora_stream = 1;
	}

	de_dbg(c, "bitstream type: %s", si->sti?si->sti->name:"unknown");
}
Esempio n. 16
0
static int read_pam_header_line(deark *c, lctx *d, struct page_ctx *pg, de_int64 pos,
	de_int64 *content_len, de_int64 *total_len,
	char *linebuf, size_t linebuf_len)
{
	int ret;
	de_int64 amt_to_read;

	linebuf[0]='\0';

	ret = dbuf_find_line(c->infile, pos,
		content_len, total_len);

	if(!ret) return 0;

	amt_to_read = *content_len;
	if(amt_to_read > (de_int64)(linebuf_len-1)) amt_to_read = (de_int64)(linebuf_len-1);

	de_read((de_byte*)linebuf, pos, amt_to_read);

	*content_len = amt_to_read;
	linebuf[amt_to_read] = '\0';
	return 1;
}
Esempio n. 17
0
File: rpm.c Progetto: jsummers/deark
static void de_run_rpm(deark *c, de_module_params *mparams)
{
	lctx *d = NULL;
	i64 pos;
	u8 buf[8];
	const char *ext;
	i64 section_size = 0;
	de_finfo *fi = NULL;
	char filename[128];

	d = de_malloc(c, sizeof(lctx));

	if(!do_lead_section(c, d)) {
		goto done;
	}

	pos = 96;

	if(!do_header_structure(c, d, 1, pos, &section_size)) {
		goto done;
	}
	pos += section_size;

	// Header structures are 8-byte aligned. The first one always starts at
	// offset 96, so we don't have to worry about it. But we need to make
	// sure the second one is aligned.
	pos = ((pos + 7)/8)*8;

	if(!do_header_structure(c, d, 0, pos, &section_size)) {
		goto done;
	}
	pos += section_size;

	de_dbg(c, "data pos: %d", (int)pos);
	if(pos > c->infile->len) goto done;

	// There is usually a tag that indicates the compression format, but we
	// primarily figure out the format by sniffing its magic number, on the
	// theory that that's more reliable.

	// TODO: I think it's also theoretically possible that it could use an archive
	// format other than cpio.

	de_read(buf, pos, 8);

	if(buf[0]==0x1f && buf[1]==0x8b) {
		ext = "cpio.gz";
	}
	else if(buf[0]==0x42 && buf[1]==0x5a && buf[2]==0x68) {
		ext = "cpio.bz2";
	}
	else if(buf[0]==0xfd && buf[1]==0x37 && buf[2]==0x7a) {
		ext = "cpio.xz";
	}
	else if(d->cmpr_type==DE_RPM_CMPR_LZMA || buf[0]==0x5d) {
		ext = "cpio.lzma";
	}
	else {
		de_warn(c, "Unidentified compression or archive format");
		ext = "cpio.bin";
	}

	if(d->name_srd && c->filenames_from_file) {
		const char *version2 = "x";
		const char *release2 = "x";

		if(d->version_srd) version2 = d->version_srd->sz;
		if(d->release_srd) release2 = d->release_srd->sz;

		fi = de_finfo_create(c);
		de_snprintf(filename, sizeof(filename), "%s-%s.%s",
			d->name_srd->sz, version2, release2);
		de_finfo_set_name_from_sz(c, fi, filename, 0, DE_ENCODING_ASCII);
	}

	dbuf_create_file_from_slice(c->infile, pos, c->infile->len - pos, ext, fi, 0);

done:
	de_finfo_destroy(c, fi);
	if(d) {
		de_destroy_stringreaderdata(c, d->name_srd);
		de_destroy_stringreaderdata(c, d->release_srd);
		de_destroy_stringreaderdata(c, d->version_srd);
		de_free(c, d);
	}
}
Esempio n. 18
0
File: rpm.c Progetto: jsummers/deark
// Note that a header *structure* is distinct from the header *section*.
// Both the signature section and the header section use a header structure.
static int do_header_structure(deark *c, lctx *d, int is_sig, i64 pos1,
	i64 *section_size)
{
	i64 pos;
	i64 indexcount;
	i64 storesize;
	u8 buf[4];
	u8 header_ver;
	i64 i;
	i64 tag_id, tag_type, tag_offset, tag_count;
	i64 data_store_pos;
	const char *hdrname;
	int retval = 0;

	hdrname = is_sig?"sig":"hdr";
	pos = pos1;
	de_dbg(c, "%s section at %d", hdrname, (int)pos1);
	de_dbg_indent(c, 1);

	de_read(buf, pos, 4);
	if(buf[0]!=0x8e || buf[1]!=0xad || buf[2]!=0xe8) {
		de_err(c, "Bad header signature at %d", (int)pos);
		goto done;
	}
	header_ver = buf[3];
	if(header_ver != 1) {
		de_err(c, "Unsupported header version");
		goto done;
	}
	pos += 8;

	indexcount = de_getu32be(pos);
	storesize = de_getu32be(pos+4);
	de_dbg(c, "%s: pos=%d indexcount=%d storesize=%d", hdrname,
		(int)pos, (int)indexcount, (int)storesize);
	pos += 8;

	if(indexcount>1000) goto done;

	data_store_pos = pos + 16*indexcount;

	de_dbg(c, "%s: tag table at %d", hdrname, (int)pos);
	de_dbg_indent(c, 1);

	for(i=0; i<indexcount; i++) {
		tag_id = de_getu32be(pos);
		tag_type = de_getu32be(pos+4);
		tag_offset = de_getu32be(pos+8);
		tag_count = de_getu32be(pos+12);

		de_dbg2(c, "tag #%d type=%d offset=%d count=%d", (int)tag_id,
			(int)tag_type, (int)tag_offset, (int)tag_count);


		if(is_sig==0 && tag_id==DE_RPMTAG_PAYLOADCOMPRESSOR && tag_type==DE_RPM_STRING_TYPE) {
			read_compression_type(c, d, data_store_pos+tag_offset);
		}
		else if(is_sig==0 && tag_id==DE_RPMTAG_NAME && tag_type==DE_RPM_STRING_TYPE) {
			if(!d->name_srd) {
				d->name_srd = dbuf_read_string(c->infile, data_store_pos+tag_offset,
					DE_DBG_MAX_STRLEN, DE_DBG_MAX_STRLEN,
					DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII);
				de_dbg(c, "name: \"%s\"", ucstring_getpsz(d->name_srd->str));
			}
		}
		else if(is_sig==0 && tag_id==DE_RPMTAG_VERSION && tag_type==DE_RPM_STRING_TYPE) {
			if(!d->version_srd) {
				d->version_srd = dbuf_read_string(c->infile, data_store_pos+tag_offset,
					DE_DBG_MAX_STRLEN, DE_DBG_MAX_STRLEN,
					DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII);
				de_dbg(c, "version: \"%s\"", ucstring_getpsz(d->version_srd->str));
			}
		}
		else if(is_sig==0 && tag_id==DE_RPMTAG_RELEASE && tag_type==DE_RPM_STRING_TYPE) {
			if(!d->release_srd) {
				d->release_srd = dbuf_read_string(c->infile, data_store_pos+tag_offset,
					DE_DBG_MAX_STRLEN, DE_DBG_MAX_STRLEN,
					DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII);
				de_dbg(c, "release: \"%s\"", ucstring_getpsz(d->release_srd->str));
			}
		}

		pos += 16;
	}

	de_dbg_indent(c, -1);

	pos = data_store_pos;
	de_dbg(c, "%s: data store at %d", hdrname, (int)pos);
	pos += storesize;

	*section_size = pos - pos1;
	retval = 1;
done:
	de_dbg_indent(c, -1);
	return retval;
}
Esempio n. 19
0
File: wri.c Progetto: jsummers/deark
// pos1 points to the ole_id field (should be 0x00000501).
// Caller must have looked ahead to check the type.
static int do_picture_ole_embedded_rendition(deark *c, lctx *d, struct para_info *pinfo,
	int rendition_idx, i64 pos1, i64 *bytes_consumed)
{
	i64 pos = pos1;
	i64 stringlen;
	i64 data_len;
	u8 buf[16];
	struct de_stringreaderdata *srd_typename = NULL;
	struct de_stringreaderdata *srd_filename = NULL;
	struct de_stringreaderdata *srd_params = NULL;

	pos += 4; // 0x00000501
	pos += 4; // "type" (probably already read by caller)

	stringlen = de_getu32le_p(&pos);
	srd_typename = dbuf_read_string(c->infile, pos, stringlen, 260, DE_CONVFLAG_STOP_AT_NUL,
		DE_ENCODING_ASCII);
	de_dbg(c, "typename: \"%s\"", ucstring_getpsz(srd_typename->str));
	pos += stringlen;

	stringlen = de_getu32le_p(&pos);
	srd_filename = dbuf_read_string(c->infile, pos, stringlen, 260, DE_CONVFLAG_STOP_AT_NUL,
		DE_ENCODING_ASCII);
	de_dbg(c, "filename: \"%s\"", ucstring_getpsz(srd_filename->str));
	pos += stringlen;

	stringlen = de_getu32le_p(&pos);
	srd_params = dbuf_read_string(c->infile, pos, stringlen, 260, DE_CONVFLAG_STOP_AT_NUL,
		DE_ENCODING_ASCII);
	de_dbg(c, "params: \"%s\"", ucstring_getpsz(srd_params->str));
	pos += stringlen;

	data_len = de_getu32le_p(&pos);
	de_dbg(c, "embedded ole rendition data: pos=%d, len=%d", (int)pos, (int)data_len);

	// TODO: I don't know the extent to which it's better to sniff the data, or
	// rely on the typename.
	de_read(buf, pos, sizeof(buf));

	if(!de_strcmp(srd_typename->sz, "CDraw") &&
		!de_memcmp(&buf[0], (const void*)"RIFF", 4) &&
		!de_memcmp(&buf[8], (const void*)"CDR", 3) )
	{
		// Looks like CorelDRAW
		dbuf_create_file_from_slice(c->infile, pos, data_len, "cdr", NULL, 0);
	}
	else if(buf[0]=='B' && buf[1]=='M') {
		// TODO: Detect true length of data
		dbuf_create_file_from_slice(c->infile, pos, data_len, "bmp", NULL, 0);
	}
	else {
		if(d->extract_ole) {
			extract_unknown_ole_obj(c, d, pos, data_len, srd_typename);
		}
		else {
			de_warn(c, "Unknown/unsupported type of OLE object (\"%s\") at %d",
				ucstring_getpsz(srd_typename->str), (int)pos1);
		}
	}

	pos += data_len;
	*bytes_consumed = pos - pos1;

	de_destroy_stringreaderdata(c, srd_typename);
	de_destroy_stringreaderdata(c, srd_filename);
	de_destroy_stringreaderdata(c, srd_params);
	return 1;
}
Esempio n. 20
0
// Caller must initialize *repeat_count.
static void uncompress_line(deark *c, lctx *d, dbuf *unc_line,
	i64 pos1, i64 rownum,
	i64 *bytes_consumed, i64 *repeat_count)
{
	i64 pos;
	u8 b0, b1;
	u8 val;
	i64 count;
	i64 k;
	i64 tmp_repeat_count;
	i64 unc_line_len_orig;

	*bytes_consumed = 0;
	pos = pos1;
	unc_line_len_orig = unc_line->len;

	while(1) {
		if(pos >= c->infile->len) break;
		if(unc_line->len - unc_line_len_orig >= d->rowspan_per_plane) break;

		b0 = de_getbyte(pos++);

		if(b0==0) { // Pattern run or scanline run
			b1 = de_getbyte(pos++);
			if(b1>0) { // pattern run
				de_read(d->pattern_buf, pos, d->patlen);
				pos += d->patlen;
				count = (i64)b1;
				for(k=0; k<count; k++) {
					dbuf_write(unc_line, d->pattern_buf, d->patlen);
				}
			}
			else { // (b1==0) scanline run
				u8 flagbyte;
				flagbyte = de_getbyte(pos);
				if(flagbyte==0xff) {
					pos++;
					tmp_repeat_count = (i64)de_getbyte(pos++);
					if(tmp_repeat_count == 0) {
						de_dbg(c, "row %d: bad repeat count", (int)rownum);
					}
					else {
						*repeat_count = tmp_repeat_count;
					}
				}
				else {
					de_dbg(c, "row %d: bad scanline run marker: 0x%02x",
						(int)rownum, (unsigned int)flagbyte);
				}
			}
		}
		else if(b0==0x80) { // "Uncompressed bit string"
			count = (i64)de_getbyte(pos++);
			dbuf_copy(c->infile, pos, count, unc_line);
			pos += count;
		}
		else { // "solid run"
			val = (b0&0x80) ? 0xff : 0x00;
			count = (i64)(b0 & 0x7f);
			dbuf_write_run(unc_line, val, count);
		}
	}

	*bytes_consumed = pos - pos1;
}
Esempio n. 21
0
static void do_psf2_unicode_table(deark *c, lctx *d, struct de_bitmap_font *font)
{
	de_int64 cur_idx;
	de_int64 pos;
	int ret;
	de_int64 foundpos;
	de_int64 char_data_len;
	de_byte char_data_buf[200];
	de_int32 ch;
	de_int64 utf8len;

	de_dbg(c, "Unicode table at %d\n", (int)d->unicode_table_pos);
	de_dbg_indent(c, 1);

	pos = d->unicode_table_pos;
	cur_idx = 0;
	while(1) {
		de_int64 pos_in_char_data;
		de_int64 cp_idx;

		if(cur_idx >= d->num_glyphs) break;
		if(pos >= c->infile->len) break;

		// Figure out the size of the data for this glyph
		ret = dbuf_search_byte(c->infile, 0xff, pos,
			c->infile->len - pos, &foundpos);
		if(!ret) break;
		char_data_len = foundpos - pos;
		if(char_data_len<0) char_data_len=0;
		else if(char_data_len>(de_int64)sizeof(char_data_buf)) char_data_len=(de_int64)sizeof(char_data_buf);

		// Read all the data for this glyph
		de_read(char_data_buf, pos, char_data_len);

		// Read the codepoints for this glyph
		cp_idx = 0;
		pos_in_char_data = 0;
		while(1) {
			if(pos_in_char_data >= char_data_len) break;

			ret = de_utf8_to_uchar(&char_data_buf[pos_in_char_data], char_data_len-pos_in_char_data,
				&ch, &utf8len);
			if(!ret) {
				// If there are any multi-codepoint aliases for this glyph, we
				// expect de_utf8_to_uchar() to fail when it hits the 0xfe byte.
				// So, this is not necessarily an error.
				break;
			}

			if(cp_idx==0) {
				// This is the primary Unicode codepoint for this glyph
				de_dbg2(c, "char[%d] = U+%04x\n", (int)cur_idx, (unsigned int)ch);
				font->char_array[cur_idx].codepoint_unicode = ch;
			}
			else {
				do_extra_codepoint(c, d, font, cur_idx, ch);
			}

			cp_idx++;
			pos_in_char_data += utf8len;
		}

		if(cp_idx==0) {
			de_warn(c, "Missing codepoint for char #%d\n", (int)cur_idx);
		}

		// Advance to the next glyph
		pos = foundpos+1;
		cur_idx++;
	}

	font->has_unicode_codepoints = 1;
	font->prefer_unicode = 1;

	de_dbg_indent(c, -1);
}