コード例 #1
0
static void do_uncompress_24(deark *c, lctx *d, struct page_ctx *pg, dbuf *unc_pixels,
	de_int64 skip)
{
	de_int64 pos;
	de_byte b;
	de_int64 count;
	de_byte n;

	pos = pg->image_pos;
	if(skip) pos+=4;

	while(1) {
		if(pos >= pg->image_pos + pg->image_len) break;

		b = de_getbyte(pos);
		pos++;
		if(b>=128) {
			// Compressed run
			count = (de_int64)b - 125;
			n = de_getbyte(pos);
			pos++;
			dbuf_write_run(unc_pixels, n, count);
		}
		else {
			// An uncompressed run
			count = 1 + (de_int64)b;
			dbuf_copy(c->infile, pos, count, unc_pixels);
			pos += count;
		}
	}
}
コード例 #2
0
static void do_dir_entry(deark *c, lctx *d, de_int64 entry_num, de_int64 pos)
{
	de_byte filetype_c64s;
	de_byte filetype;

	filetype_c64s = de_getbyte(pos);
	if(filetype_c64s==0) {
		de_dbg2(c, "unused entry #%d at %d\n", (int)entry_num, (int)pos);
		return;
	}
	de_dbg(c, "entry #%d at %d\n", (int)entry_num, (int)pos);

	de_dbg_indent(c, 1);

	filetype = de_getbyte(pos+1);
	de_dbg(c, "c64s filetype=%d, filetype=0x%02x\n", (int)filetype_c64s, (int)filetype);

	if(filetype==0x00) {
		de_err(c, "Unsupported file type (0x%02x)\n", (int)filetype);
	}
	else {
		do_extract_file(c, d, pos, filetype_c64s, filetype);
	}

	de_dbg_indent(c, -1);
}
コード例 #3
0
static void do_psf1_header(deark *c, lctx *d)
{
	de_int64 pos = 0;

	de_dbg(c, "PFXv1 header at %d\n", (int)pos);
	de_dbg_indent(c, 1);

	d->headersize = 4;

	d->mode = de_getbyte(2);
	de_dbg(c, "mode: 0x%02x\n", (unsigned int)d->mode);
	de_dbg_indent(c, 1);
	d->num_glyphs = (d->mode & 0x01) ? 512 : 256;
	de_dbg(c, "number of glyphs: %d\n", (int)d->num_glyphs);
	d->has_unicode_table = (d->mode & 0x02) ? 1 : 0;
	de_dbg(c, "has Unicode table: %s\n", d->has_unicode_table?"yes":"no");
	de_dbg_indent(c, -1);

	d->bytes_per_glyph = (de_int64)de_getbyte(3);
	d->glyph_height = d->bytes_per_glyph;
	d->glyph_width = 8;
	de_dbg(c, "glyph dimensions: %dx%d\n", (int)d->glyph_width, (int)d->glyph_height);

	de_dbg_indent(c, -1);
}
コード例 #4
0
ファイル: png.c プロジェクト: jsummers/deark
static void handler_IHDR(deark *c, lctx *d, struct handler_params *hp)
{
	i64 w, h;
	u8 n;
	const char *name;

	if(hp->dlen<13) return;
	w = de_getu32be(hp->dpos);
	h = de_getu32be(hp->dpos+4);
	de_dbg_dimensions(c, w, h);

	n = de_getbyte(hp->dpos+8);
	de_dbg(c, "depth: %d bits/sample", (int)n);

	d->color_type = de_getbyte(hp->dpos+9);
	switch(d->color_type) {
	case 0: name="grayscale"; break;
	case 2: name="truecolor"; break;
	case 3: name="palette"; break;
	case 4: name="grayscale+alpha"; break;
	case 6: name="truecolor+alpha"; break;
	default: name="?";
	}
	de_dbg(c, "color type: %d (%s)", (int)d->color_type, name);

	n = de_getbyte(hp->dpos+12);
	de_dbg(c, "interlaced: %d", (int)n);
}
コード例 #5
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));
		}
コード例 #6
0
ファイル: png.c プロジェクト: jsummers/deark
static void handler_sPLT(deark *c, lctx *d, struct handler_params *hp)
{
	struct de_stringreaderdata *srd = NULL;
	i64 pos = hp->dpos;
	i64 nbytes_to_scan;
	u8 depth;
	i64 nentries;
	i64 stride;
	i64 i;

	nbytes_to_scan = hp->dlen;
	if(nbytes_to_scan>80) nbytes_to_scan=80;
	srd = dbuf_read_string(c->infile, pos, nbytes_to_scan, 79, DE_CONVFLAG_STOP_AT_NUL,
		DE_ENCODING_LATIN1);
	if(!srd->found_nul) goto done;
	de_dbg(c, "palette name: \"%s\"", ucstring_getpsz(srd->str));
	pos += srd->bytes_consumed;

	if(pos >= hp->dpos+hp->dlen) goto done;
	depth = de_getbyte(pos++);
	de_dbg(c, "depth: %d", (int)depth);
	if(depth!=8 && depth!=16) goto done;

	stride = (depth==8) ? 6 : 10;
	nentries = (hp->dpos+hp->dlen-pos)/stride;
	de_dbg(c, "number of entries: %d", (int)nentries);

	if(c->debug_level<2) goto done;
	for(i=0; i<nentries; i++) {
		unsigned int cr, cg, cb, ca, cf;
		if(depth==8) {
			cr = (unsigned int)de_getbyte(pos);
			cg = (unsigned int)de_getbyte(pos+1);
			cb = (unsigned int)de_getbyte(pos+2);
			ca = (unsigned int)de_getbyte(pos+3);
			cf = (unsigned int)de_getu16be(pos+4);
			de_dbg2(c, "pal[%3d] = (%3u,%3u,%3u,A=%u) F=%u",
				(int)i, cr, cg, cb, ca, cf);
		}
		else {
			cr = (unsigned int)de_getu16be(pos);
			cg = (unsigned int)de_getu16be(pos+2);
			cb = (unsigned int)de_getu16be(pos+4);
			ca = (unsigned int)de_getu16be(pos+6);
			cf = (unsigned int)de_getu16be(pos+8);
			de_dbg2(c, "pal[%3d] = (%5u,%5u,%5u,A=%u) F=%u",
				(int)i, cr, cg, cb, ca, cf);
		}
		pos += stride;
	}

done:
	de_destroy_stringreaderdata(c, srd);
}
コード例 #7
0
static int do_image_pgm_ppm_binary(deark *c, lctx *d, struct page_ctx *pg, de_int64 pos1)
{
	struct deark_bitmap *img = NULL;
	de_int64 rowspan;
	de_int64 nsamples; // For both input and output
	de_int64 bytes_per_sample;
	de_int64 i, j, k;
	de_int64 pos = pos1;
	unsigned int samp_ori[3];
	de_byte samp_adj[3];

	if(fmt_is_ppm(pg->fmt)) nsamples=3;
	else nsamples=1;

	if(pg->maxval<=255) bytes_per_sample=1;
	else bytes_per_sample=2;

	rowspan = pg->width * nsamples * bytes_per_sample;
	pg->image_data_len = rowspan * pg->height;

	img = de_bitmap_create(c, pg->width, pg->height, (int)nsamples);

	for(j=0; j<pg->height; j++) {
		for(i=0; i<pg->width; i++) {
			for(k=0; k<nsamples; k++) {
				if(bytes_per_sample==1) {
					samp_ori[k] = de_getbyte(pos++);
				}
				else {
					samp_ori[k] = (unsigned int)de_getbyte(pos++) << 8 ;
					samp_ori[k] |= (unsigned int)de_getbyte(pos++);
				}

				samp_adj[k] = de_scale_n_to_255(pg->maxval, samp_ori[k]);
			}

			if(nsamples==1) {
				de_bitmap_setpixel_gray(img, i, j, samp_adj[0]);
			}
			else {
				de_uint32 clr;
				clr = DE_MAKE_RGB(samp_adj[0], samp_adj[1], samp_adj[2]);
				de_bitmap_setpixel_rgb(img, i, j, clr);
			}
		}
	}

	de_bitmap_write_to_file(img, NULL, 0);

	de_bitmap_destroy(img);
	return 1;
}
コード例 #8
0
ファイル: tga.c プロジェクト: jsummers/deark
// This .vst (TrueVista) decoder is based on guesswork, on the limited information
// in the TGA spec, and on the behavior of XnView. It may not be correct.
static int do_read_vst_headers(deark *c, lctx *d)
{
	int retval = 0;

	de_dbg(c, "header at %d", 0);
	de_dbg_indent(c, 1);

	d->id_field_len = (i64)de_getbyte(0);

	if(d->id_field_len==0) {
		// ??? XnView seems to do something like this.
		d->id_field_len=18;
	}

	d->cmpr_type = TGA_CMPR_NONE;
	d->cmpr_name = "none";

	d->main_image.width = de_getu16le(12);
	d->main_image.height = de_getu16le(14);
	de_dbg_dimensions(c, d->main_image.width, d->main_image.height);

	d->pixel_depth = (i64)de_getbyte(16);
	de_dbg(c, "pixel depth: %d", (int)d->pixel_depth);
	if(d->pixel_depth==8) {
		d->color_map_type = 1;
		d->color_type = TGA_CLRTYPE_PALETTE;
		d->clrtype_name = "palette";
	}
	else {
		d->color_type = TGA_CLRTYPE_TRUECOLOR;
		d->clrtype_name = "truecolor";
	}

	if(d->color_type==TGA_CLRTYPE_PALETTE) {
		d->cmap_start = 0;
		d->cmap_length = 256;
		d->cmap_depth = 24;
	}

	do_read_image_descriptor(c, d);

	de_dbg_indent(c, -1);

	if(!de_good_image_dimensions(c, d->main_image.width, d->main_image.height)) goto done;

	retval = 1;
done:
	return retval;
}
コード例 #9
0
static int do_image_pbm_ascii(deark *c, lctx *d, struct page_ctx *pg, de_int64 pos1)
{
	struct deark_bitmap *img = NULL;
	de_int64 xpos, ypos;
	de_int64 pos = pos1;
	de_byte b;
	de_byte v;

	img = de_bitmap_create(c, pg->width, pg->height, 1);

	xpos=0; ypos=0;
	while(1) {
		if(pos >= c->infile->len) break; // end of file
		if(ypos==(pg->height-1) && xpos>=pg->width) break; // end of image
		if(ypos>=pg->height) break;

		b = de_getbyte(pos++);
		if(b=='1') v=0;
		else if(b=='0') v=255;
		else continue;

		de_bitmap_setpixel_gray(img, xpos, ypos, v);
		xpos++;
		if(xpos>=pg->width) {
			ypos++;
			xpos=0;
		}
	}

	de_bitmap_write_to_file_finfo(img, NULL, 0);
	de_bitmap_destroy(img);
	return 1;
}
コード例 #10
0
// Some OS/2v2 files exist with bad (3-bytes/color) palettes.
// Try to detect them.
static void do_os2v2_bad_palette(deark *c, lctx *d)
{
	de_int64 pal_space_avail;
	de_int64 pal_bytes_if_3bpc;
	de_int64 pal_bytes_if_4bpc;
	int nonzero_rsvd;
	int i;

	if(d->version!=DE_BMPVER_OS2V2) return;
	if(d->pal_entries<1) return;

	pal_space_avail = d->bits_offset - d->pal_pos;
	pal_bytes_if_4bpc = 4*d->pal_entries;
	pal_bytes_if_3bpc = 3*d->pal_entries;

	if(pal_space_avail>=pal_bytes_if_4bpc) return;
	if(pal_space_avail<pal_bytes_if_3bpc || pal_space_avail>(pal_bytes_if_3bpc+1)) return;

	// Look for nonzero 'reserved' bytes
	nonzero_rsvd = 0;
	for(i=0; i<pal_bytes_if_3bpc; i+=4) {
		if(de_getbyte(d->pal_pos + i + 3) != 0) {
			nonzero_rsvd = 1;
			break;
		}
	}
	if(!nonzero_rsvd) return;

	de_warn(c, "Assuming palette has 3 bytes per entry, instead of 4\n");
	d->bytes_per_pal_entry = 3;
}
コード例 #11
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;
	}
}
コード例 #12
0
static void de_run_cardfile(deark *c, de_module_params *mparams)
{
	lctx *d = NULL;
	de_byte b;
	de_int64 pos;
	de_int64 n;

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

	pos = 0;
	b = de_getbyte(pos);
	if(b=='R') d->fmt=DE_CRDFMT_RRG;
	else d->fmt=DE_CRDFMT_MGC;

	if(d->fmt==DE_CRDFMT_RRG) {
		de_err(c, "CardFile RRG format is not supported\n");
		goto done;
	}

	pos+=3;

	d->numcards = de_getui16le(pos);
	de_dbg(c, "number of cards: %d\n", (int)d->numcards);
	pos+=2;

	for(n=0; n<d->numcards; n++) {
		do_card_index(c, d, n, pos);
		pos+=52;
	}

done:
	de_free(c, d);
}
コード例 #13
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);
}
コード例 #14
0
ファイル: tga.c プロジェクト: 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;
}
コード例 #15
0
ファイル: png.c プロジェクト: jsummers/deark
static void handler_orNT(deark *c, lctx *d, struct handler_params *hp)
{
	u8 n;
	if(hp->dlen!=1) return;
	n = de_getbyte(hp->dpos);
	de_dbg(c, "orientation: %d (%s)", (int)n, de_fmtutil_tiff_orientation_name((i64)n));
}
コード例 #16
0
ファイル: png.c プロジェクト: jsummers/deark
static void handler_tRNS(deark *c, lctx *d, struct handler_params *hp)
{
	i64 r, g, b;

	if(d->color_type==0) {
		if(hp->dlen<2) return;
		r = de_getu16be(hp->dpos);
		de_dbg(c, "transparent color gray shade: %d", (int)r);
	}
	else if(d->color_type==2) {
		if(hp->dlen<6) return;
		r = de_getu16be(hp->dpos);
		g = de_getu16be(hp->dpos+2);
		b = de_getu16be(hp->dpos+4);
		de_dbg(c, "transparent color: (%d,%d,%d)", (int)r, (int)g, (int)b);
	}
	else if(d->color_type==3) {
		i64 i;
		u8 a;

		de_dbg(c, "number of alpha values: %d", (int)hp->dlen);
		if(c->debug_level<2) return;
		for(i=0; i<hp->dlen && i<256; i++) {
			a = de_getbyte(hp->dpos+i);
			de_dbg2(c, "alpha[%3d] = %d", (int)i, (int)a);
		}
	}
}
コード例 #17
0
ファイル: wad.c プロジェクト: jsummers/deark
static int de_identify_wad(deark *c)
{
	if(!dbuf_memcmp(c->infile, 1, "WAD", 3)) {
		u8 b0;
		b0 = de_getbyte(0);
		if(b0=='I' || b0=='P') return 80;
	}
	return 0;
}
コード例 #18
0
static int de_identify_iptc(deark *c)
{
	de_byte b;

	// First byte of each dataset is 0x1c.
	if(de_getbyte(0)!=0x1c) return 0;

	// Check the record number. Record numbers 1-9 are known.
	b = de_getbyte(1);
	if(b<1 || b>15) return 0;

	// This is not meant to imply that .iptc is an official file extension for
	// IPTC data. It's just that it's used by Deark when extracting IPTC data
	// to a file.
	if(!de_input_file_has_ext(c, "iptc")) return 0;

	return 60;
}
コード例 #19
0
static void de_run_psf(deark *c, de_module_params *mparams)
{
	lctx *d = NULL;
	de_byte b;
	const char *s;

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

	s = de_get_ext_option(c, "font:noaliases");
	if(s)
		d->read_extra_codepoints = 0;
	else
		d->read_extra_codepoints = 1;

	b = de_getbyte(0);
	if(b==0x36) {
		d->version=1;
	}
	else if(b==0x72) {
		d->version=2;
	}
	else {
		de_err(c, "Not a PSF file\n");
		goto done;
	}

	de_dbg(c, "PSF version: %d\n", (int)d->version);

	if(d->version==2)
		do_psf2_header(c, d);
	else
		do_psf1_header(c, d);

	d->font_data_size = d->bytes_per_glyph * d->num_glyphs;
	if(d->has_unicode_table) {
		d->unicode_table_pos = d->headersize + d->font_data_size;
		if(d->unicode_table_pos >= c->infile->len) {
			d->has_unicode_table = 0;
		}
	}

	if((d->headersize+d->font_data_size > c->infile->len) ||
		d->bytes_per_glyph<1 ||
		d->glyph_width<1 || d->glyph_width>256 ||
		d->glyph_height<1 || d->glyph_height>256 ||
		d->num_glyphs<1 || d->num_glyphs>2000000)
	{
		de_err(c, "Invalid or unsupported PSF file\n");
		goto done;
	}

	do_glyphs(c, d);

done:
	de_free(c, d);
}
コード例 #20
0
ファイル: png.c プロジェクト: jsummers/deark
static void handler_tIME(deark *c, lctx *d, struct handler_params *hp)
{
	i64 yr;
	u8 mo, da, hr, mi, se;
	struct de_timestamp ts;
	char timestamp_buf[64];

	yr = de_getu16be(hp->dpos);
	mo = de_getbyte(hp->dpos+2);
	da = de_getbyte(hp->dpos+3);
	hr = de_getbyte(hp->dpos+4);
	mi = de_getbyte(hp->dpos+5);
	se = de_getbyte(hp->dpos+6);

	de_make_timestamp(&ts, yr, mo, da, hr, mi, se);
	ts.tzcode = DE_TZCODE_UTC;
	de_timestamp_to_string(&ts, timestamp_buf, sizeof(timestamp_buf), 0);
	de_dbg(c, "mod time: %s", timestamp_buf);
}
コード例 #21
0
ファイル: rpm.c プロジェクト: jsummers/deark
static int do_lead_section(deark *c, lctx *d)
{
	int retval = 0;

	de_dbg(c, "lead section at %d", 0);
	de_dbg_indent(c, 1);

	d->ver_major = de_getbyte(4);
	d->ver_minor = de_getbyte(5);
	de_dbg(c, "RPM format version: %d.%d", (int)d->ver_major, (int)d->ver_minor);
	if(d->ver_major < 3) {
		de_err(c, "Unsupported RPM version (%d.%d)", (int)d->ver_major, (int)d->ver_minor);
		goto done;
	}

	retval = 1;
done:
	de_dbg_indent(c, -1);
	return retval;
}
コード例 #22
0
static int read_pam_header(deark *c, lctx *d, struct page_ctx *pg, de_int64 pos1)
{
	int ret;
	de_int64 pos = pos1;
	int retval = 0;
	char linebuf[200];
	char token1buf[200];
	//char token2buf[200];

	de_dbg(c, "header at %d\n", (int)pos1);
	de_dbg_indent(c, 1);

	de_err(c, "PAM format not supported\n");
	goto done;

	pos += 3; // Skip "P7\n"
	while(1) {
		de_int64 content_len;
		de_int64 total_len;
		de_int64 curpos;

		//ret = dbuf_find_line(c->infile, pos,
		//	&content_len, &total_len);
		ret = read_pam_header_line(c, d, pg, pos, &content_len, &total_len,
			linebuf, sizeof(linebuf));

		if(!ret) {
			de_err(c, "Invalid PAM header\n");
			break;
		}

		if(content_len>0 && (de_getbyte(pos)=='#')) {
			// comment line
			pos += total_len;
			continue;
		}

		curpos = 0;
		if(!read_next_pam_token(c, d, pg, linebuf, token1buf, sizeof(token1buf), &curpos)) goto done;

		if(!de_strcmp(token1buf,"ENDHDR")) {
			break;
		}

		pos += total_len;
		continue;

	}

	retval = 1;
done:
	de_dbg_indent(c, -1);
	return retval;
}
コード例 #23
0
ファイル: tga.c プロジェクト: jsummers/deark
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);
}
コード例 #24
0
ファイル: ebml.c プロジェクト: jsummers/deark
// Print an element ID number, in the format used by the Matroska spec.
static void print_encoded_id(deark *c, lctx *d, i64 pos, i64 len)
{
	de_ucstring *s = NULL;
	i64 i;

	if(len>8) return;
	s = ucstring_create(c);
	for(i=0; i<len; i++) {
		ucstring_printf(s, DE_ENCODING_UTF8, "[%02x]",
			(unsigned int)de_getbyte(pos+i));
	}
	de_dbg(c, "encoded id: %s", ucstring_getpsz_d(s));
	ucstring_destroy(s);
}
コード例 #25
0
ファイル: wri.c プロジェクト: jsummers/deark
static void do_para_fprop(deark *c, lctx *d, struct para_info *pinfo,
	i64 bfprop, u8 is_dup)
{
	i64 fprop_dlen = 0;

	// bfprop is a pointer into the 123 bytes of data starting
	// at pos+4. The maximum sensible value is at most 122.
	if(bfprop<=122) {
		// It appears that the length prefix does not include itself,
		// contrary to what one source says.
		fprop_dlen = (i64)de_getbyte(pinfo->bfprop_offset);
		if(!is_dup) de_dbg(c, "fprop dlen: %d", (int)fprop_dlen);
	}

	if(fprop_dlen>=2) {
		pinfo->justification = de_getbyte(pinfo->bfprop_offset + 1 + 1) & 0x03;
		if(!is_dup && pinfo->justification!=0) {
			de_dbg(c, "justification: %d", (int)pinfo->justification);
		}
	}

	if(fprop_dlen>=17) {
		pinfo->papflags = de_getbyte(pinfo->bfprop_offset + 1 + 16);
		if(!is_dup) {
			de_ucstring *flagstr = ucstring_create(c);
			if(pinfo->papflags&0x06) {
				ucstring_append_flags_item(flagstr, (pinfo->papflags&0x01)?"footer":"header");
				ucstring_append_flags_item(flagstr, (pinfo->papflags&0x08)?"print on first page":
					"do not print on first page");
			}
			if(pinfo->papflags&0x10) ucstring_append_flags_item(flagstr, "picture");
			de_dbg(c, "paragraph flags: 0x%02x (%s)", (unsigned int)pinfo->papflags,
				ucstring_getpsz(flagstr));
			ucstring_destroy(flagstr);
		}
	}
}
コード例 #26
0
ファイル: ogg.c プロジェクト: jsummers/deark
static void do_vorbis_page(deark *c, lctx *d, struct page_info *pgi, struct stream_info *si)
{
	u8 firstbyte;

	if(pgi->is_first_page) {
		// The first Ogg page of a bitstream usually contains enough data to be
		// useful. So, we'll try to process it directly, without reconstructing
		// the codec bitstream.
		do_vorbis_id_header(c, d, pgi, si);
	}

	// We want to save a copy of the Comment and Setup header data,
	// but not the Identification header which is handled elsewhere.

	if(si->stream_state!=0) {
		// We've already handled the Comment & Setup headers.
		goto done;
	}

	if(pgi->dlen<1) goto done;

	firstbyte = de_getbyte(pgi->dpos);

	if(si->page_count==0 || pgi->page_seq_num==0 || (pgi->hdr_type&0x02)) {
		// This appears to be the Identification header page. Skip it.
		goto done;
	}

	if(pgi->page_seq_num>=1 && (firstbyte&0x01)) {
		// This appears to be one of the pages we care about.
		// Save its data for later.
		if(!si->header_stream) {
			si->header_stream = dbuf_create_membuf(c, 1048576, 1);
		}
		dbuf_copy(c->infile, pgi->dpos, pgi->dlen, si->header_stream);
	}
	else if((firstbyte&0x01)==0) {
		// Reached the end of headers (by encountering a non-header page).
		// (There is required to be an Ogg page break immediately after the
		// Vorbis headers, so the start of the first data *page* must correspond
		// to the start of the first data *packet*. A Vorbis data packet always
		// begins with a byte whose low bit is 0.)
		do_theora_vorbis_after_headers(c, d, si);
	}

done:
	;
}
コード例 #27
0
ファイル: png.c プロジェクト: jsummers/deark
static void handler_sRGB(deark *c, lctx *d, struct handler_params *hp)
{
	u8 intent;
	const char *name;

	if(hp->dlen<1) return;
	intent = de_getbyte(hp->dpos);
	switch(intent) {
	case 0: name="perceptual"; break;
	case 1: name="relative"; break;
	case 2: name="saturation"; break;
	case 3: name="absolute"; break;
	default: name="?";
	}
	de_dbg(c, "rendering intent: %d (%s)", (int)intent, name);
}
コード例 #28
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);
}
コード例 #29
0
ファイル: png.c プロジェクト: jsummers/deark
static void handler_pHYs(deark *c, lctx *d, struct handler_params *hp)
{
	i64 dx, dy;
	u8 u;
	const char *name;

	dx = de_getu32be(hp->dpos);
	dy = de_getu32be(hp->dpos+4);
	de_dbg(c, "density: %d"DE_CHAR_TIMES"%d", (int)dx, (int)dy);
	u = de_getbyte(hp->dpos+8);
	switch(u) {
	case 0: name="unspecified"; break;
	case 1: name="per meter"; break;
	default: name="?";
	}
	de_dbg(c, "units: %d (%s)", (int)u, name);
}
コード例 #30
0
static int read_next_token(deark *c, lctx *d, struct page_ctx *pg,
	char *tokenbuf, size_t tokenbuflen)
{
	de_byte b;
	size_t token_len = 0;
	int in_comment = 0;

	token_len = 0;
	while(1) {
		if(pg->hdr_parse_pos >= c->infile->len) return 0;

		if(token_len >= tokenbuflen) {
			return 0; // Token too long.
		}

		b = de_getbyte(pg->hdr_parse_pos++);

		if(in_comment) {
			if(b==10 || b==13) {
				in_comment = 0;
			}
			continue;
		}
		else if(b=='#') {
			in_comment = 1;
			continue;
		}
		else if(is_pnm_whitespace(b)) {
			if(token_len>0) {
				tokenbuf[token_len] = '\0';
				return 1;
			}
			else {
				continue; // Skip leading whitespace.
			}
		}
		else {
			// Append the character to the token.
			tokenbuf[token_len] = (char)b;
			token_len++;
		}
	}

	return 0;
}