Exemple #1
0
static void de_run_gzip(deark *c, de_module_params *mparams)
{
	lctx *d = NULL;
	i64 pos;
	i64 member_size;

	d = de_malloc(c, sizeof(lctx));
	d->crco = de_crcobj_create(c, DE_CRCOBJ_CRC32_IEEE);

	pos = 0;
	while(1) {
		if(pos >= c->infile->len) break;
		if(!do_gzip_read_member(c, d, pos, &member_size)) {
			break;
		}
		if(member_size<=0) break;

		pos += member_size;
	}
	dbuf_close(d->output_file);

	if(d) {
		de_crcobj_destroy(d->crco);
		de_free(c, d);
	}
}
Exemple #2
0
static void do_read_bitmap(deark *c, lctx *d, de_int64 pos)
{
	de_int64 ver_num;
	dbuf *unc_pixels = NULL;

	ver_num = de_getui32be(pos);
	de_dbg(c, "version number: %u\n", (unsigned int)ver_num);
	if(ver_num!=0 && ver_num!=2 && ver_num!=3) {
		de_warn(c, "Unrecognized version number: %u\n", (unsigned int)ver_num);
	}

	pos += 512;

	unc_pixels = dbuf_create_membuf(c, MACPAINT_IMAGE_BYTES, 1);

	de_fmtutil_uncompress_packbits(c->infile, pos, c->infile->len - pos, unc_pixels, NULL);

	if(unc_pixels->len < MACPAINT_IMAGE_BYTES) {
		de_warn(c, "Image decompressed to %d bytes, expected %d.\n",
			(int)unc_pixels->len, (int)MACPAINT_IMAGE_BYTES);
	}

	de_convert_and_write_image_bilevel(unc_pixels, 0,
		MACPAINT_WIDTH, MACPAINT_HEIGHT, MACPAINT_WIDTH/8,
		DE_CVTF_WHITEISZERO, NULL, 0);

	dbuf_close(unc_pixels);
}
Exemple #3
0
static void do_extract_file(deark *c, lctx *d, de_int64 dir_pos,
	de_byte filetype_c64s, de_byte filetype)
{
	de_int64 load_addr;
	de_int64 end_addr;
	de_int64 offset;
	dbuf *f = NULL;
	de_int64 payload_size; // = file_size-2
	de_ucstring *fname = NULL;
	de_int64 fname_len;
	de_int64 i;
	de_int64 fnpos;
	de_finfo *fi = NULL;

	load_addr = de_getui16le(dir_pos+2);
	end_addr = de_getui16le(dir_pos+4);
	offset = de_getui32le(dir_pos+8);
	de_dbg(c, "load_addr=%d end_addr=%d offset=%d\n", (int)load_addr,
		(int)end_addr, (int)offset);

	// File name at pos+16

	fnpos = dir_pos+16;

	// Find the length of the (space-padded) filename.
	fname_len = 0;
	for(i=15; i>=0; i--) {
		if(de_getbyte(fnpos+i)!=' ') {
			fname_len = i+1;
			break;
		}
	}
	de_dbg2(c, "filename length: %d\n", (int)fname_len);

	fname = ucstring_create(c);
	dbuf_read_to_ucstring(c->infile, fnpos, fname_len, fname, 0, DE_ENCODING_PETSCII);
	de_dbg(c, "filename: \"%s\"\n", ucstring_get_printable_sz(fname));

	ucstring_append_sz(fname, ".prg", DE_ENCODING_ASCII);

	fi = de_finfo_create(c);
	de_finfo_set_name_from_ucstring(c, fi, fname);
	fi->original_filename_flag = 1;

	payload_size = end_addr - load_addr;
	if(payload_size < 0) {
		// TODO: Try to support files that don't have end_addr set properly.
		de_err(c, "This type of T64 file is not supported.\n");
		goto done;
	}

	f = dbuf_create_output_file(c, NULL, fi, 0);
	dbuf_copy(c->infile, dir_pos+2, 2, f);
	dbuf_copy(c->infile, offset, payload_size, f);

done:
	dbuf_close(f);
	de_finfo_destroy(c, fi);
	ucstring_destroy(fname);
}
Exemple #4
0
static void do_html_end(deark *c, lctx *d)
{
	if(!d->html_outf) return;
	dbuf_puts(d->html_outf, "</body>\n</html>\n");
	dbuf_close(d->html_outf);
	d->html_outf = NULL;
}
Exemple #5
0
// Rasterized caption
static void handle_2_125(deark *c, lctx *d, const struct ds_info *dsi,
	de_int64 pos, de_int64 len)
{
	dbuf *unc_pixels = NULL;
	struct deark_bitmap *img = NULL;
	de_int64 i, j;
	de_byte b;
	de_int64 rowspan;
	de_int64 width, height;

	// I can't find any examples of this field, so this may not be correct.
	// The format seems to be well-documented, though the pixels are in an
	// unusual order.

	unc_pixels = dbuf_open_input_subfile(c->infile, pos, len);
	width = 460;
	height = 128;
	img = de_bitmap_create(c, width, height, 1);
	rowspan = height/8;

	for(j=0; j<width; j++) {
		for(i=0; i<height; i++) {
			b = de_get_bits_symbol(unc_pixels, 1, rowspan*j, i);
			de_bitmap_setpixel_gray(img, j, (height-1-i), b?0:255);
		}
	}

	de_bitmap_write_to_file(img, "caption", DE_CREATEFLAG_IS_AUX);
	de_bitmap_destroy(img);
	dbuf_close(unc_pixels);
}
Exemple #6
0
int dbuf_create_file_from_slice(dbuf *inf, i64 pos, i64 data_size,
	const char *ext, de_finfo *fi, unsigned int createflags)
{
	dbuf *f;
	f = dbuf_create_output_file(inf->c, ext, fi, createflags);
	if(!f) return 0;
	dbuf_copy(inf, pos, data_size, f);
	dbuf_close(f);
	return 1;
}
Exemple #7
0
static int do_gem_img(deark *c, lctx *d)
{
	dbuf *unc_pixels = NULL;
	de_bitmap *img = NULL;
	de_finfo *fi = NULL;
	int is_color = 0;
	i64 k;

	if(d->header_size_in_words==9 && (d->nplanes==3 || d->nplanes==4)) {
		i64 x;
		x = de_getu16be(8*2);
		if(x==0) {
			is_color = 1;
		}
	}

	de_dbg(c, "image at %d", (int)d->header_size_in_bytes);

	unc_pixels = dbuf_create_membuf(c, d->rowspan_total*d->h, 0);

	uncompress_pixels(c, d, unc_pixels, d->header_size_in_bytes, c->infile->len-d->header_size_in_bytes);

	img = de_bitmap_create(c, d->w, d->h, is_color?3:1);

	fi = de_finfo_create(c);
	set_density(c, d, fi);

	if(d->nplanes==1) {
		de_convert_image_bilevel(unc_pixels, 0, d->rowspan_per_plane, img, DE_CVTF_WHITEISZERO);
	}
	else if(is_color && d->nplanes==3) {
		for(k=0; k<8; k++) {
			d->pal[k] = pal3bit[k];
		}
		read_paletted_image(c, d, unc_pixels, img);
	}
	else if(is_color && d->nplanes==4) {
		for(k=0; k<16; k++) {
			d->pal[k] = pal4bit[k];
		}
		read_paletted_image(c, d, unc_pixels, img);
	}
	else {
		de_make_grayscale_palette(d->pal, ((i64)1)<<((unsigned int)d->nplanes), 1);
		read_paletted_image(c, d, unc_pixels, img);
	}

	de_bitmap_write_to_file_finfo(img, fi, 0);

	de_bitmap_destroy(img);
	de_finfo_destroy(c, fi);
	dbuf_close(unc_pixels);
	return 1;
}
Exemple #8
0
static void handler_iccp(deark *c, lctx *d, struct handler_params *hp)
{
	u8 cmpr_type;
	dbuf *f = NULL;
	struct de_stringreaderdata *prof_name_srd = NULL;
	de_finfo *fi = NULL;
	char prof_name2[100];
	size_t prof_name2_strlen;
	i64 pos = hp->dpos;

	prof_name_srd = dbuf_read_string(c->infile, pos, 80, 80,
		DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_LATIN1);
	if(!prof_name_srd->found_nul) goto done;
	de_dbg(c, "profile name: \"%s\"", ucstring_getpsz_d(prof_name_srd->str));
	pos += prof_name_srd->bytes_consumed;

	// Our working copy, to use as part of the filename.
	de_strlcpy(prof_name2, prof_name_srd->sz, sizeof(prof_name2));
	if(!de_strcasecmp(prof_name2, "icc") ||
		!de_strcasecmp(prof_name2, "icc profile"))
	{
		prof_name2[0] = '\0'; // Ignore generic name.
	}

	prof_name2_strlen = de_strlen(prof_name2);
	if(prof_name2_strlen>=5) {
		if(de_sz_has_ext(prof_name2, "icc")) {
			// If the name already ends in ".icc", chop it off so that we don't end
			// up with a double ".icc.icc" file extension.
			prof_name2[prof_name2_strlen-4] = '\0';
		}
	}

	cmpr_type = de_getbyte_p(&pos);
	if(cmpr_type!=0) return;

	fi = de_finfo_create(c);
	if(c->filenames_from_file && prof_name2[0])
		de_finfo_set_name_from_sz(c, fi, prof_name2, 0, DE_ENCODING_LATIN1);
	f = dbuf_create_output_file(c, "icc", fi, DE_CREATEFLAG_IS_AUX);
	de_decompress_deflate(c->infile, pos, hp->dlen - pos, f, 0, NULL,
		d->is_CgBI ? 0 : DE_DEFLATEFLAG_ISZLIB);

done:
	dbuf_close(f);
	de_finfo_destroy(c, fi);
	de_destroy_stringreaderdata(c, prof_name_srd);
}
Exemple #9
0
static void destroy_bitstream(deark *c, lctx *d, struct stream_info *si)
{
	if(!si) return;

	if((si->stream_type==STREAMTYPE_VORBIS || si->stream_type==STREAMTYPE_THEORA)
		&& si->stream_state==0)
	{
		do_theora_vorbis_after_headers(c, d, si);
	}

	if(si->header_stream) {
		dbuf_close(si->header_stream);
	}

	de_free(c, si);
}
Exemple #10
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);
}
Exemple #11
0
static void uncompress_pixels(deark *c, lctx *d, dbuf *unc_pixels,
	i64 pos1, i64 len)
{
	i64 bytes_consumed;
	i64 pos;
	i64 ypos;
	i64 repeat_count;
	i64 k;
	i64 plane;
	dbuf *unc_line = NULL;

	d->pattern_buf = de_malloc(c, d->patlen);
	unc_line = dbuf_create_membuf(c, d->rowspan_total, 0);

	pos = pos1;

	ypos = 0;
	while(1) {
		if(ypos >= d->h) break;

		repeat_count = 1;

		dbuf_empty(unc_line);
		for(plane=0; plane<d->nplanes; plane++) {
			uncompress_line(c, d, unc_line,
				pos, ypos, &bytes_consumed, &repeat_count);
			pos+=bytes_consumed;
			if(bytes_consumed<1) goto done1;
		}

		for(k=0; k<repeat_count; k++) {
			if(ypos >= d->h) break;
			dbuf_copy(unc_line, 0, d->rowspan_total, unc_pixels);
			ypos++;
		}
	}
done1:
	dbuf_close(unc_line);
	de_free(c, d->pattern_buf);
	d->pattern_buf = NULL;
}
Exemple #12
0
static void do_theora_vorbis_after_headers(deark *c, lctx *d, struct stream_info *si)
{
	i64 pos = 0;
	int saved_indent_level;
	dbuf *f = NULL;

	de_dbg_indent_save(c, &saved_indent_level);
	if(si->stream_state!=0) goto done;
	if(!si->header_stream) goto done;
	if(!si->sti) goto done;
	f = si->header_stream;

	de_dbg(c, "[decoding %s comment/setup headers, %d bytes]",
		si->sti->name, (int)si->header_stream->len);
	de_dbg_indent(c, 1);

	// Make sure the comment header signature is present.
	if(si->stream_type==STREAMTYPE_VORBIS) {
		if(dbuf_memcmp(f, 0, "\x03" "vorbis", 7)) {
			goto done;
		}
		pos += 7;
	}
	else if(si->stream_type==STREAMTYPE_THEORA) {
		if(dbuf_memcmp(f, 0, "\x81" "theora", 7)) {
			goto done;
		}
		pos += 7;
	}

	do_vorbis_comment_block(c, d, f, pos);

	// TODO: "Setup" header

done:
	si->stream_state = 1;
	dbuf_close(si->header_stream);
	si->header_stream = NULL;
	de_dbg_indent_restore(c, saved_indent_level);
}
Exemple #13
0
static void de_run_gzip(deark *c, de_module_params *mparams)
{
	lctx *d = NULL;
	de_int64 pos;
	de_int64 member_size;

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

	pos = 0;
	while(1) {
		if(pos >= c->infile->len) break;
		if(!do_gzip_read_member(c, d, pos, &member_size)) {
			break;
		}
		if(member_size<=0) break;

		pos += member_size;
	}
	dbuf_close(d->output_file);

	de_free(c, d);
}
Exemple #14
0
static void do_decode_thumbnail(deark *c, lctx *d)
{
	dbuf *unc_pixels = NULL;
	i64 hdrsize = 2;

	de_dbg(c, "thumbnail image at %d", (int)d->thumbnail_offset);
	de_dbg_indent(c, 1);

	// The thumbnail image is supposed to use the same format as the main image,
	// except without compression. (And the dimensions are obviously different.)
	// Presumably this means the origin, palette, etc. will be the same.
	// But based on the few TGA thumbnails we've seen, nobody reads the spec, and
	// it's anybody's guess what format the thumbnail will use.

	// TGA 2.0 spec says the dimensions are one *byte* each.
	d->thumbnail_image.width = (i64)de_getbyte(d->thumbnail_offset);
	d->thumbnail_image.height = (i64)de_getbyte(d->thumbnail_offset+1);
	de_dbg(c, "thumbnail dimensions: %d"DE_CHAR_TIMES"%d", (int)d->thumbnail_image.width, (int)d->thumbnail_image.height);

	if(d->thumbnail_image.width!=0 && d->thumbnail_image.height==0) {
		de_warn(c, "Thumbnail image height is 0. Assuming the file incorrectly uses "
			"16-bit thumbnail dimensions, instead of 8.");
		d->thumbnail_image.width = de_getu16le(d->thumbnail_offset);
		d->thumbnail_image.height = de_getu16le(d->thumbnail_offset+2);
		de_dbg(c, "revised thumbnail dimensions: %d"DE_CHAR_TIMES"%d", (int)d->thumbnail_image.width, (int)d->thumbnail_image.height);
		hdrsize = 4;
	}
	if(!de_good_image_dimensions(c, d->thumbnail_image.width, d->thumbnail_image.height)) goto done;

	d->thumbnail_image.img_size_in_bytes = d->thumbnail_image.height * d->thumbnail_image.width * d->bytes_per_pixel;
	unc_pixels = dbuf_open_input_subfile(c->infile, d->thumbnail_offset+hdrsize, d->thumbnail_image.img_size_in_bytes);

	do_decode_image(c, d, &d->thumbnail_image, unc_pixels, "thumb", DE_CREATEFLAG_IS_AUX);

done:
	dbuf_close(unc_pixels);
	de_dbg_indent(c, -1);
}
Exemple #15
0
// Caption/abstract
static void handle_2_120(deark *c, lctx *d, const struct ds_info *dsi,
	de_int64 pos, de_int64 len)
{
	de_ucstring *s = NULL;
	dbuf *outf = NULL;
	int encoding;
	const char *fntoken;

	if(c->extract_level<2) {
		handle_text(c, d, dsi, pos, len);
		goto done;
	}

	// FIXME: There is currently no way to extract IPTC captions to files,
	// except when reading a raw IPTC file. If IPTC is embedded in some other
	// file (as it usually is), then the -a option will extract the entire
	// IPTC data, and we will never get here.

	fntoken = "caption.txt";

	encoding = get_ds_encoding(c, d, dsi->recnum);
	if(encoding==DE_ENCODING_UNKNOWN) {
		// If the encoding is unknown, copy the raw bytes.
		dbuf_create_file_from_slice(c->infile, pos, len, fntoken,
			NULL, DE_CREATEFLAG_IS_AUX);
		goto done;
	}

	// If the encoding is known, convert to UTF-8.
	s = ucstring_create(c);
	dbuf_read_to_ucstring(c->infile, pos, len, s, 0, encoding);
	outf = dbuf_create_output_file(c, fntoken, NULL, DE_CREATEFLAG_IS_AUX);
	ucstring_write_as_utf8(c, s, outf, 1);

done:
	if(outf) dbuf_close(outf);
	if(s) ucstring_destroy(s);
}
Exemple #16
0
// Read and process the keyword, language, translated keyword, or main text
// field of a tEXt/zTXt/iTXt chunk.
// 'bytes_consumed' does not include the NUL separator/terminator.
// This is a wrapper that first decompresses the field if necessary.
static int do_text_field(deark *c, lctx *d,
	struct text_chunk_ctx *tcc, int which_field,
	i64 pos, i64 bytes_avail,
	int is_nul_terminated, int is_compressed, int encoding,
	i64 *bytes_consumed)
{
	dbuf *tmpdbuf = NULL;
	int retval = 0;
	i64 bytes_consumed2;

	if(!is_compressed) {
		retval = do_unc_text_field(c, d, tcc,
			which_field, c->infile, pos, bytes_avail,
			is_nul_terminated, encoding, bytes_consumed);
		goto done;
	}

	// Decompress to a membuf, then call do_unc_text_field() with that membuf.
	// Note that a compressed field cannot be NUL-terminated.
	*bytes_consumed = bytes_avail;

	tmpdbuf = dbuf_create_membuf(c, 0, 0);
	if(!de_decompress_deflate(c->infile, pos, bytes_avail, tmpdbuf, 0, NULL,
		d->is_CgBI ? 0 : DE_DEFLATEFLAG_ISZLIB))
	{
		goto done;
	}

	retval = do_unc_text_field(c, d, tcc,
		which_field, tmpdbuf, 0, tmpdbuf->len,
		0, encoding, &bytes_consumed2);

done:
	dbuf_close(tmpdbuf);
	return retval;
}
Exemple #17
0
void de_run(deark *c)
{
	dbuf *orig_ifile = NULL;
	dbuf *subfile = NULL;
	de_int64 subfile_size;
	struct deark_module_info *module_to_use = NULL;
	const char *friendly_infn;

	if(c->modhelp_req && c->input_format_req) {
		do_modhelp(c);
		goto done;
	}

	if(c->input_style==DE_INPUTSTYLE_STDIN) {
		friendly_infn = "[stdin]";
	}
	else {
		friendly_infn = c->input_filename;
	}

	if(!friendly_infn) {
		de_err(c, "Input file not set\n");
		de_fatalerror(c);
		return;
	}

	de_register_modules(c);

	if(c->input_format_req) {
		module_to_use = de_get_module_by_id(c, c->input_format_req);
		if(!module_to_use) {
			de_err(c, "Unknown module \"%s\"\n", c->input_format_req);
			goto done;
		}
	}

	if(c->slice_size_req_valid) {
		de_dbg(c, "Input file: %s[%d,%d]\n", friendly_infn,
			(int)c->slice_start_req, (int)c->slice_size_req);
	}
	else if(c->slice_start_req) {
		de_dbg(c, "Input file: %s[%d]\n", friendly_infn,
			(int)c->slice_start_req);
	}
	else {
		de_dbg(c, "Input file: %s\n", friendly_infn);
	}

	if(c->input_style==DE_INPUTSTYLE_STDIN) {
		orig_ifile = dbuf_open_input_stdin(c, c->input_filename);
	}
	else {
		orig_ifile = dbuf_open_input_file(c, c->input_filename);
	}
	if(!orig_ifile) {
		goto done;
	}

	c->infile = orig_ifile;

	// If we are only supposed to look at a segment of the original file,
	// do that by creating a child dbuf, using dbuf_open_input_subfile().
	if(c->slice_start_req>0 || c->slice_size_req_valid) {
		if(c->slice_size_req_valid)
			subfile_size = c->slice_size_req;
		else
			subfile_size = dbuf_get_length(c->infile) - c->slice_start_req;
		subfile = dbuf_open_input_subfile(c->infile, c->slice_start_req, subfile_size);
		c->infile = subfile;
	}

	if(!module_to_use) {
		module_to_use = detect_module_for_file(c);
	}

	if(!module_to_use) {
		if(c->infile->len==0)
			de_err(c, "Unknown or unsupported file format (empty file)\n");
		else
			de_err(c, "Unknown or unsupported file format\n");
		goto done;
	}

	de_msg(c, "Module: %s\n", module_to_use->id);
	if(module_to_use->flags&DE_MODFLAG_NONWORKING) {
		de_warn(c, "The %s module is considered to be incomplete, and may "
			"not work properly. Caveat emptor.\n",
			module_to_use->id);
	}
	de_dbg2(c, "file size: %" INT64_FMT "\n", c->infile->len);

	if(!de_run_module(c, module_to_use, NULL)) {
		goto done;
	}

	// The DE_MODFLAG_NOEXTRACT flag means the module is not expected to extract
	// any files.
	if(c->num_files_extracted==0 && c->error_count==0 &&
		!(module_to_use->flags&DE_MODFLAG_NOEXTRACT))
	{
		de_msg(c, "No files found to extract!\n");
	}

done:
	if(subfile) dbuf_close(subfile);
	if(orig_ifile) dbuf_close(orig_ifile);
}
Exemple #18
0
// XIMG and similar formats.
// TODO: Should this function be merged with do_gem_img()?
static int do_gem_ximg(deark *c, lctx *d)
{
	dbuf *unc_pixels = NULL;
	de_bitmap *img = NULL;
	de_finfo *fi = NULL;
	int retval = 0;
	int saved_indent_level;

	de_dbg_indent_save(c, &saved_indent_level);

	de_dbg(c, "header (continued) at %d", 8*2);
	de_dbg_indent(c, 1);

	if((d->nplanes>=1 && d->nplanes<=8) /* || d->nplanes==24 */) {
		;
	}
	else {
		if(d->is_ximg)
			de_err(c, "%d-plane XIMG images are not supported", (int)d->nplanes);
		else
			de_err(c, "This type of %d-plane image is not supported", (int)d->nplanes);
		goto done;
	}

	if(d->header_size_in_words==25 && !d->is_ximg) {
		i64 pal_pos = d->header_size_in_bytes-32;
		de_dbg(c, "palette at %d", (int)pal_pos);
		de_dbg_indent(c, 1);
		de_fmtutil_read_atari_palette(c, c->infile, pal_pos,
			d->pal, 16, ((i64)1)<<d->nplanes, 0);
		de_dbg_indent(c, -1);
	}
	else {
		read_palette_ximg(c, d);
	}

	if(d->nplanes==1 && d->pal[0]==d->pal[1]) {
		de_dbg(c, "Palette doesn't seem to be present. Using a default palette.");
		d->pal[0] = DE_STOCKCOLOR_WHITE;
		d->pal[1] = DE_STOCKCOLOR_BLACK;
	}

	de_dbg_indent(c, -1);

	de_dbg(c, "image at %d", (int)d->header_size_in_bytes);

	unc_pixels = dbuf_create_membuf(c, d->rowspan_total*d->h, 0);
	uncompress_pixels(c, d, unc_pixels, d->header_size_in_bytes, c->infile->len-d->header_size_in_bytes);

	img = de_bitmap_create(c, d->w, d->h, 3);

	fi = de_finfo_create(c);
	set_density(c, d, fi);

	if(d->nplanes>8) {
		read_rgb_image(c, d, unc_pixels, img);
	}
	else {
		read_paletted_image(c, d, unc_pixels, img);
	}

	de_bitmap_write_to_file_finfo(img, fi, 0);

	retval = 1;

done:
	de_bitmap_destroy(img);
	de_finfo_destroy(c, fi);
	dbuf_close(unc_pixels);
	de_dbg_indent_restore(c, saved_indent_level);
	return retval;
}
Exemple #19
0
static void de_run_tga(deark *c, de_module_params *mparams)
{
	lctx *d = NULL;
	i64 pos;
	dbuf *unc_pixels = NULL;
	int saved_indent_level;
	i64 rowspan_tmp;

	de_dbg_indent_save(c, &saved_indent_level);
	d = de_malloc(c, sizeof(lctx));

	detect_file_format(c, d);

	if(d->file_format==FMT_VST) {
		de_declare_fmt(c, "TrueVista");
	}
	else {
		de_declare_fmt(c, "TGA");
	}

	pos = 0;

	if(d->file_format==FMT_VST) {
		if(!do_read_vst_headers(c, d)) goto done;
	}
	else {
		if(!do_read_tga_headers(c, d)) goto done;
	}
	pos += 18;

	if(d->id_field_len>0) {
		de_dbg(c, "image ID at %d (len=%d)", (int)pos, (int)d->id_field_len);
		pos += d->id_field_len;
	}

	if(d->color_map_type!=0) {
		d->bytes_per_pal_entry = (d->cmap_depth+7)/8;
		d->pal_size_in_bytes = d->cmap_length * d->bytes_per_pal_entry;
		de_dbg(c, "color map at %d (%d colors, %d bytes)", (int)pos,
			(int)d->cmap_length, (int)d->pal_size_in_bytes);

		de_dbg_indent(c, 1);
		if(!do_read_palette(c, d, pos)) goto done;
		de_dbg_indent(c, -1);

		pos += d->pal_size_in_bytes;
	}

	de_dbg(c, "bitmap at %d", (int)pos);
	de_dbg_indent(c, 1);

	d->bytes_per_pixel = ((d->pixel_depth+7)/8);
	if(d->pixel_depth==1) {
		rowspan_tmp = (d->main_image.width+7)/8;
	}
	else {
		rowspan_tmp = d->main_image.width * d->bytes_per_pixel;
	}
	d->main_image.img_size_in_bytes = d->main_image.height * rowspan_tmp;

	if(d->color_type!=TGA_CLRTYPE_PALETTE && d->color_type!=TGA_CLRTYPE_TRUECOLOR &&
		d->color_type!=TGA_CLRTYPE_GRAYSCALE)
	{
		de_err(c, "Unsupported color type (%d: %s)", (int)d->color_type, d->clrtype_name);
		goto done;
	}

	if( (d->color_type==TGA_CLRTYPE_PALETTE && d->pixel_depth==8) ||
		(d->color_type==TGA_CLRTYPE_TRUECOLOR && d->pixel_depth==15) ||
		(d->color_type==TGA_CLRTYPE_TRUECOLOR && d->pixel_depth==16) ||
		(d->color_type==TGA_CLRTYPE_TRUECOLOR && d->pixel_depth==24) ||
		(d->color_type==TGA_CLRTYPE_TRUECOLOR && d->pixel_depth==32) ||
		(d->color_type==TGA_CLRTYPE_GRAYSCALE && d->pixel_depth==1) ||
		(d->color_type==TGA_CLRTYPE_GRAYSCALE && d->pixel_depth==8) )
	{
		;
	}
	else {
		de_err(c, "Unsupported TGA image type (%s, depth=%d)", d->clrtype_name,
			(int)d->pixel_depth);
		goto done;
	}

	if(d->cmpr_type==TGA_CMPR_RLE) {
		if(d->pixel_depth<8) {
			de_err(c, "RLE compression not supported when depth (%d) is less than 8",
				(int)d->pixel_depth);
			goto done;
		}
		unc_pixels = dbuf_create_membuf(c, d->main_image.img_size_in_bytes, 1);
		if(!do_decode_rle(c, d, pos, unc_pixels)) goto done;
	}
	else if(d->cmpr_type==TGA_CMPR_NONE) {
		unc_pixels = dbuf_open_input_subfile(c->infile, pos, d->main_image.img_size_in_bytes);
	}
	else {
		de_err(c, "Unsupported compression type (%d, %s)", (int)d->cmpr_type, d->cmpr_name);
		goto done;
	}

	// Maybe scan the image, to help detect transparency.
	do_prescan_image(c, d, unc_pixels);

	if(d->pixel_depth==32) {
		de_dbg(c, "using alpha channel: %s", d->has_alpha_channel?"yes":"no");
	}

	// TODO: 16-bit images could theoretically have a transparency bit, but I don't
	// know how to detect that.

	do_decode_image(c, d, &d->main_image, unc_pixels, NULL, 0);

	de_dbg_indent(c, -1);

	if(d->thumbnail_offset!=0) {
		do_decode_thumbnail(c, d);
	}

done:
	dbuf_close(unc_pixels);
	de_dbg_indent_restore(c, saved_indent_level);
	de_free(c, d);
}
Exemple #20
0
// Generic (ImageMagick?) profile. Hex-encoded, with three header lines.
static void on_im_generic_profile_main(deark *c, lctx *d,
	struct text_chunk_ctx *tcc, dbuf *inf, i64 pos1, i64 len)
{
	int k;
	i64 pos = pos1;
	i64 dlen;
	int dump_to_file = 0;
	int decode_to_membuf = 0;
	const char *ext = NULL;

	// Skip the first three lines
	for(k=0; k<3; k++) {
		int ret;
		i64 foundpos = 0;
		ret = dbuf_search_byte(inf, 0x0a, pos, pos1+len-pos, &foundpos);
		if(!ret) goto done;
		pos = foundpos+1;
	}
	dlen = pos1+len-pos;

	if(tcc->im_generic_profile_type==PROFILETYPE_XMP) {
		dump_to_file = 1;
		ext = "xmp";
	}
	else if(tcc->im_generic_profile_type==PROFILETYPE_8BIM) {
		decode_to_membuf = 1;
	}
	else if(tcc->im_generic_profile_type==PROFILETYPE_IPTC) {
		if(c->extract_level>=2) {
			dump_to_file = 1;
			ext = "iptc";
		}
		else {
			decode_to_membuf = 1;
		}
	}
	else if(tcc->im_generic_profile_type==PROFILETYPE_ICC) {
		dump_to_file = 1;
		ext = "icc";
	}
	else {
		if(c->extract_level>=2) {
			dump_to_file = 1;
			ext = "profile.bin";
		}
	}

	if(dump_to_file) {
		dbuf *outf;
		outf = dbuf_create_output_file(c, ext?ext:"bin", NULL, DE_CREATEFLAG_IS_AUX);
		de_decode_base16(c, inf, pos, dlen, outf, 0);
		dbuf_close(outf);
	}

	if(decode_to_membuf) {
		dbuf *tmpf;

		tmpf = dbuf_create_membuf(c, 0, 0);
		de_decode_base16(c, inf, pos, dlen, tmpf, 0);

		if(tcc->im_generic_profile_type==PROFILETYPE_8BIM) {
			de_fmtutil_handle_photoshop_rsrc(c, tmpf, 0, tmpf->len, 0x0);
		}
		else if(tcc->im_generic_profile_type==PROFILETYPE_IPTC) {
			de_fmtutil_handle_iptc(c, tmpf, 0, tmpf->len, 0x0);
		}

		dbuf_close(tmpf);
	}

done:
	;
}
Exemple #21
0
static void de_run_alphabmp(deark *c, de_module_params *mparams)
{
	unsigned int flags;
	lctx *d = NULL;
	i64 pos;
	i64 palsize;
	dbuf *unc_pixels = NULL;
	int saved_indent_level;

	de_dbg_indent_save(c, &saved_indent_level);

	d = de_malloc(c, sizeof(lctx));
	de_declare_fmt(c, "Alpha Microsystems BMP");

	pos = 10;

	de_dbg(c, "bitmap image definition block at %d", (int)pos);
	de_dbg_indent(c, 1);

	d->w = de_getu16le(pos);
	d->h = de_getu16le(pos+2);
	de_dbg_dimensions(c, d->w, d->h);
	if(!de_good_image_dimensions(c, d->w, d->h)) goto done;

	d->bpp = de_getu16le(pos+4);
	de_dbg(c, "bits/pixel: %d", (int)d->bpp);

	flags = (unsigned int)de_getu16le(pos+6);
	d->has_palette = flags & 0x01;
	d->palette_is_hls = (flags>>1) & 0x01;
	de_dbg(c, "has-palette: %d", (int)d->has_palette);
	if(d->has_palette)
		de_dbg(c, "palette-is-HLS: %d", (int)d->palette_is_hls);

	d->compression = de_getu16le(pos+8);
	de_dbg(c, "compression: %d", (int)d->compression);
	de_dbg_indent(c, -1);

	pos += 70;

	if(d->has_palette) {
		if(d->palette_is_hls && d->bpp<=8) {
			de_err(c, "HLS palettes are not supported");
			goto done;
		}
		if(!do_read_palette(c, d, pos, &palsize)) goto done;
		pos += palsize;
	}
	else if(d->bpp<=8) {
		de_err(c, "Paletted images without an embedded palette are not supported");
		goto done;
	}

	de_dbg(c, "bitmap at %d", (int)pos);
	de_dbg_indent(c, 1);

	if(d->compression) {
		unc_pixels = dbuf_create_membuf(c, 32768, 0);
		if(!do_uncompress_image(c, d, pos, unc_pixels)) goto done;
	}
	else {
		unc_pixels = dbuf_open_input_subfile(c->infile, pos, c->infile->len - pos);
	}

	if(d->bpp!=1 && d->bpp!=4 && d->bpp!=8 && d->bpp!=24) {
		de_err(c, "%d bits/pixel is not supported", (int)d->bpp);
		goto done;
	}

	do_bitmap(c, d, unc_pixels);
	de_dbg_indent(c, -1);

done:
	de_dbg_indent_restore(c, saved_indent_level);
	dbuf_close(unc_pixels);
	de_free(c, d);
}