Example #1
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);
}
Example #2
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;
		}
	}
}
Example #3
0
File: tga.c Project: 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;
}
Example #4
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;
}
Example #5
0
File: ogg.c Project: 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:
	;
}
Example #6
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;
}
Example #7
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;
}
Example #8
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;
}
Example #9
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;
}