예제 #1
0
static void de_run_macpaint(deark *c, de_module_params *mparams)
{
	lctx *d;
	de_int64 pos;
	const char *s;

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

	d->has_macbinary_header = -1;

	s = de_get_ext_option(c, "macpaint:macbinary");
	if(s) d->has_macbinary_header = de_atoi(s);

	if(d->has_macbinary_header == -1) {
		int v512;
		int v640;
		de_dbg(c, "trying to determine if file has a MacBinary header\n");
		v512 = valid_file_at(c, d, 0);
		v640 = valid_file_at(c, d, 128);
		if(v512 > v640) {
			de_dbg(c, "assuming it has no MacBinary header\n");
			d->has_macbinary_header = 0;
		}
		else if(v640 > v512) {
			de_dbg(c, "assuming it has a MacBinary header\n");
			d->has_macbinary_header = 1;
		}
		else if(v512 && v640) {
			de_warn(c, "Can't determine if this file has a MacBinary header. "
				"Try \"-opt macpaint:macbinary=0\".\n");
			d->has_macbinary_header = 1;
		}
		else {
			de_warn(c, "This is probably not a MacPaint file.\n");
			d->has_macbinary_header = 1;
		}
	}

	if(d->has_macbinary_header)
		de_declare_fmt(c, "MacPaint with MacBinary header");
	else
		de_declare_fmt(c, "MacPaint without MacBinary header");

	pos = d->has_macbinary_header ? 128 : 0;

	do_read_bitmap(c, d, pos);

	do_read_patterns(c, d, pos);

	de_free(c, d);
}
예제 #2
0
static void do_opo_opa(deark *c, lctx *d)
{
	de_int64 offset_2ndheader;
	de_int64 pos;
	de_int64 n;
	de_int64 len;

	de_declare_fmt(c, "Psion OPO/OPA");

	// The second header marks the end of the embedded files section, I guess.
	offset_2ndheader = de_getui16le(18);
	de_dbg(c, "offset of second header: %d\n", (int)offset_2ndheader);
	pos = 20;

	// Read length of source filename
	n = (de_int64)de_getbyte(pos);
	pos++;
	pos+=n;
	while(pos<offset_2ndheader) {
		// Read length of this embedded file
		len = de_getui16le(pos);
		pos+=2;
		handle_embedded_file(c, d, pos, len);
		pos+=len;
	}
}
예제 #3
0
파일: bsave.c 프로젝트: jsummers/deark
// 16-color 160x100 (maybe up to 160x102) mode.
// This is really a text mode, and can be processed by do_char() as well.
static int do_cga16(deark *c, lctx *d)
{
	de_bitmap *img = NULL;
	i64 max_possible_height;
	i64 i, j;
	int retval = 0;
	u8 charcode, colorcode;
	i64 src_rowspan;
	u8 color0, color1;
	int charwarning = 0;

	de_declare_fmt(c, "BSAVE-PC 16-color CGA pseudo-graphics");

	img = de_bitmap_create_noinit(c);
	img->width = get_width(c, d, 160);
	img->height = get_height(c, d, 100);

	img->bytes_per_pixel = 3;

	// Every pair of bytes codes for two pixels; i.e. one byte per pixel.
	src_rowspan = img->width;
	max_possible_height = (d->data_size+src_rowspan-1)/src_rowspan;
	if(img->height > max_possible_height)
		img->height = max_possible_height;

	if(img->height < 1) {
		de_err(c, "Not enough data for this format");
		goto done;
	}

	for(j=0; j<img->height; j++) {
		for(i=0; i<img->width; i+=2) {
			charcode = de_getbyte(BSAVE_HDRSIZE + j*src_rowspan + i);
			colorcode = de_getbyte(BSAVE_HDRSIZE + j*src_rowspan + i+1);

			if(charwarning==0 && charcode!=0xdd && charcode!=0xde) {
				// TODO: We could also handle space characters and full-block characters,
				// at least. But maybe not worth the trouble.
				de_warn(c, "Unexpected code found (0x%02x). Format may not be correct.", (int)charcode);
				charwarning=1;
			}

			if(charcode==0xde) {
				color0 = colorcode>>4;
				color1 = colorcode&0x0f;
			}
			else {
				color1 = colorcode>>4;
				color0 = colorcode&0x0f;
			}

			de_bitmap_setpixel_rgb(img, i+0, j, de_palette_pc16(color0));
			de_bitmap_setpixel_rgb(img, i+1, j, de_palette_pc16(color1));
		}
예제 #4
0
static void do_img_app(deark *c, lctx *d)
{
	de_int64 i;
	de_int64 offset;
	de_int64 len;

	de_declare_fmt(c, "Psion IMG/APP");

	for(i=0; i<4; i++) {
		offset = de_getui16le(40 + 4*i);
		len = de_getui16le(40 + 4*i + 2);
		if(offset==0) break;
		handle_embedded_file(c, d, offset, len);
	}
}
예제 #5
0
파일: ogg.c 프로젝트: jsummers/deark
// To be called when we encounter a page that is not the first page of
// its bitstream (or at EOF).
static void declare_ogg_format(deark *c, lctx *d)
{
	char tmps[80];
	const char *name = NULL;

	if(d->format_declared) return;
	d->format_declared = 1;

	// There's no nice way, that I know of, to characterize the contents of an Ogg
	// file. But I think it's worth trying.

	if(d->bitstream_count<1) {
		// If there are zero streams : "other"
	}
	else if(d->found_ogm) {
		// else if there's an OGM stream of any kind...
		name="OGM";
	}
	else if(d->found_skeleton) {
		// else If there's a Skeleton stream...
		name="Skeleton";
	}
	else if(d->first_stream_type_valid && d->first_stream_sti &&
		!d->has_unknown_or_multiple_stream_types)
	{
		// else if all streams are the same known type: that stream type
		name = d->first_stream_sti->name;
	}
	else if(d->found_theora && d->found_vorbis && !d->has_non_vorbis_non_theora_stream) {
		// else if there are Theora and Vorbis streams and nothing else...
		name="Theora+Vorbis";
	}
	else if(d->found_theora) {
		// else if there's a Theora stream...
		name="Theora+other";
	}
	// (else "other")

	de_snprintf(tmps, sizeof(tmps), "Ogg %s", name?name:"(other)");
	de_declare_fmt(c, tmps);
}
예제 #6
0
static int do_page(deark *c, lctx *d, int pagenum, de_int64 pos1)
{
	struct page_ctx *pg = NULL;
	int retval = 0;

	pg = de_malloc(c, sizeof(struct page_ctx));

	pg->fmt = identify_fmt(c, pos1);
	d->last_fmt = pg->fmt;
	pg->fmt_name = get_fmt_name(pg->fmt);
	if(pg->fmt==0) {
		de_err(c, "Not PNM/PAM format\n");
		goto done;
	}

	if(pagenum==0) {
		de_declare_fmt(c, pg->fmt_name);
	}

	if(pg->fmt==FMT_PAM) {
		if(!read_pam_header(c, d, pg, pos1)) goto done;
	}
	else {
		if(!read_pnm_header(c, d, pg, pos1)) goto done;
	}

	if(!do_image(c, d, pg, pg->hdr_parse_pos)) {
		goto done;
	}

	d->last_bytesused = (pg->hdr_parse_pos + pg->image_data_len) - pos1;

	retval = 1;
done:
	de_free(c, pg);
	return retval;
}
예제 #7
0
파일: tga.c 프로젝트: jsummers/deark
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);
}
예제 #8
0
파일: alphabmp.c 프로젝트: jsummers/deark
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);
}
예제 #9
0
파일: png.c 프로젝트: jsummers/deark
static void de_run_png(deark *c, de_module_params *mparams)
{
	lctx *d = NULL;
	i64 pos;
	i32 prev_chunk_id = 0;
	int suppress_idat_dbg = 0;

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

	de_dbg(c, "signature at %d", 0);
	de_dbg_indent(c, 1);
	d->fmt = do_identify_png_internal(c);
	switch(d->fmt) {
	case DE_PNGFMT_PNG: d->fmt_name = "PNG"; break;
	case DE_PNGFMT_JNG: d->fmt_name = "JNG"; break;
	case DE_PNGFMT_MNG: d->fmt_name = "MNG"; break;
	default: d->fmt_name = "?";
	}
	de_dbg(c, "format: %s", d->fmt_name);
	if(d->fmt>0) {
		de_declare_fmt(c, d->fmt_name);
	}
	de_dbg_indent(c, -1);

	pos = 8;
	while(pos < c->infile->len) {
		struct de_fourcc chunk4cc;
		struct handler_params hp;
		u32 crc;
		char nbuf[80];

		de_zeromem(&hp, sizeof(struct handler_params));

		hp.dlen = de_getu32be(pos);
		if(pos + 8 + hp.dlen + 4 > c->infile->len) break;
		dbuf_read_fourcc(c->infile, pos+4, &chunk4cc, 4, 0x0);

		hp.cti = get_chunk_type_info(chunk4cc.id);

		if(chunk4cc.id==CODE_IDAT && suppress_idat_dbg) {
			;
		}
		else if(chunk4cc.id==CODE_IDAT && prev_chunk_id==CODE_IDAT && c->debug_level<2) {
			de_dbg(c, "(more IDAT chunks follow)");
			suppress_idat_dbg = 1;
		}
		else {
			if(hp.cti) {
				if(hp.cti->name) {
					de_snprintf(nbuf, sizeof(nbuf), " (%s)", hp.cti->name);
				}
				else {
					de_strlcpy(nbuf, "", sizeof(nbuf));
				}
			}
			else {
				de_strlcpy(nbuf, " (?)", sizeof(nbuf));
			}

			de_dbg(c, "chunk '%s'%s at %d dpos=%d dlen=%d",
				chunk4cc.id_dbgstr, nbuf,
				(int)pos, (int)(pos+8), (int)hp.dlen);
			if(chunk4cc.id!=CODE_IDAT) suppress_idat_dbg = 0;
		}

		pos += 8;

		de_dbg_indent(c, 1);

		hp.dpos = pos;
		hp.chunk4cc = &chunk4cc;

		if(hp.cti) {
			if(hp.cti->handler_fn) {
				hp.cti->handler_fn(c, d, &hp);
			}
		}
		else {
			if(c->debug_level>=2) {
				handler_hexdump(c, d, &hp);
			}
		}
		pos += hp.dlen;

		crc = (u32)de_getu32be(pos);
		de_dbg2(c, "crc32 (reported): 0x%08x", (unsigned int)crc);
		pos += 4;

		de_dbg_indent(c, -1);

		prev_chunk_id = chunk4cc.id;
	}

	de_free(c, d);
}
예제 #10
0
파일: gemras.c 프로젝트: jsummers/deark
static void de_run_gemraster(deark *c, de_module_params *mparams)
{
	i64 ver;
	i64 ext_word0 = 0;
	lctx *d = NULL;
	int need_format_warning = 0;
	int saved_indent_level;

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

	de_dbg(c, "header (base part) at %d", 0);
	de_dbg_indent(c, 1);
	ver = de_getu16be(0);
	de_dbg(c, "version: %d", (int)ver);
	d->header_size_in_words = de_getu16be(2);
	d->header_size_in_bytes = d->header_size_in_words*2;
	de_dbg(c, "header size: %d words (%d bytes)", (int)d->header_size_in_words,
		(int)d->header_size_in_bytes);
	d->nplanes = de_getu16be(4);
	de_dbg(c, "planes: %d", (int)d->nplanes);

	if(d->header_size_in_words>=11) {
		d->is_ximg = !dbuf_memcmp(c->infile, 16, "XIMG", 4);
	}

	d->patlen = de_getu16be(6);
	de_dbg(c, "pattern def len: %d", (int)d->patlen);
	d->pixwidth = de_getu16be(8);
	d->pixheight = de_getu16be(10);
	de_dbg(c, "pixel size: %d"DE_CHAR_TIMES"%d microns", (int)d->pixwidth, (int)d->pixheight);
	d->w = de_getu16be(12);
	d->h = de_getu16be(14);
	de_dbg_dimensions(c, d->w, d->h);
	de_dbg_indent(c, -1);

	if(d->header_size_in_words>=9) {
		// This may help to detect the image format.
		ext_word0 = de_getu16be(16);
	}

	if(ver>2) {
		de_err(c, "This version of GEM Raster (%d) is not supported.", (int)ver);
		goto done;
	}

	if(d->is_ximg) {
		de_declare_fmt(c, "GEM VDI Bit Image, XIMG extension");
	}
	else if(d->header_size_in_words==25 && d->patlen==2 && ext_word0==0x0080) {
		de_declare_fmt(c, "GEM VDI Bit Image, Hyperpaint extension");
	}
	else if(d->header_size_in_words==8 && d->nplanes==1) {
		;
	}
	else if(d->header_size_in_words==8 && (d->nplanes>=2 && d->nplanes<=8)) {
		need_format_warning = 1;
	}
	else if(d->header_size_in_words==9 && (d->nplanes>=1 && d->nplanes<=8)) {
		need_format_warning = 1;
	}
	else {
		if(d->header_size_in_words==27 && ext_word0==0x5354) {
			de_declare_fmt(c, "GEM VDI Bit Image, STTT extension");
		}
		de_err(c, "This version of GEM Raster is not supported.");
		goto done;
	}

	if(need_format_warning) {
		de_warn(c, "This type of GEM Raster image is not very portable, and might "
			"not be handled correctly.");
	}

	if(!de_good_image_dimensions(c, d->w, d->h)) goto done;

	d->rowspan_per_plane = (d->w+7)/8;
	d->rowspan_total = d->rowspan_per_plane * d->nplanes;

	// If we haven't declared the format yet, do so.
	de_declare_fmt(c, "GEM VDI Bit Image");

	if(d->is_ximg) {
		do_gem_ximg(c, d);
	}
	else if(d->header_size_in_words==25) {
		do_gem_ximg(c, d);
	}
	else {
		do_gem_img(c, d);
	}

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