Exemple #1
0
// 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));
		}
Exemple #2
0
static void do_bitmap(deark *c, lctx *d, dbuf *unc_pixels)
{
	i64 i, j;
	i64 rowspan;
	u32 clr;
	de_bitmap *img = NULL;
	u8 b;

	rowspan = (d->w * d->bpp +7)/8;

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

	for(j=0; j<d->h; j++) {
		for(i=0; i<d->w; i++) {
			if(d->bpp<=8) {
				b = de_get_bits_symbol(unc_pixels, d->bpp, j*rowspan, i);
				clr = d->pal[(unsigned int)b];
			}
			else {
				clr = dbuf_getRGB(unc_pixels, j*rowspan + i*3, 0);
			}
			de_bitmap_setpixel_rgb(img, i, j, clr);
		}
	}

	de_bitmap_write_to_file(img, NULL, 0);

	de_bitmap_destroy(img);
}
Exemple #3
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;
}
Exemple #4
0
static void do_image_24bit(deark *c, lctx *d, dbuf *bits, de_int64 bits_offset)
{
	struct deark_bitmap *img = NULL;
	de_int64 i, j;
	de_uint32 clr;

	img = bmp_bitmap_create(c, d, 3);
	for(j=0; j<d->height; j++) {
		for(i=0; i<d->width; i++) {
			clr = dbuf_getRGB(bits, bits_offset + j*d->rowspan + 3*i, DE_GETRGBFLAG_BGR);
			de_bitmap_setpixel_rgb(img, i, j, clr);
		}
	}
	de_bitmap_write_to_file(img, NULL, 0);
	de_bitmap_destroy(img);
}
Exemple #5
0
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);
}
Exemple #6
0
static void read_paletted_image(deark *c, lctx *d, dbuf *unc_pixels, de_bitmap *img)
{
	i64 i, j, plane;
	unsigned int n;
	u8 x;

	if(d->nplanes<1 || d->nplanes>8) return;

	for(j=0; j<d->h; j++) {
		for(i=0; i<d->w; i++) {
			n = 0;
			for(plane=0; plane<d->nplanes; plane++) {
				x = de_get_bits_symbol(unc_pixels, 1, j*d->rowspan_total + plane*d->rowspan_per_plane, i);
				if(x) n |= 1<<plane;
			}

			de_bitmap_setpixel_rgb(img, i, j, d->pal[n]);
		}
	}
}
Exemple #7
0
static void wri_convert_image_pal8(deark *c, i64 fpos,
	i64 rowspan, de_bitmap *img)
{
	i64 i, j;
	int badcolorflag = 0;
	// Palette is from libwps (except I might have red/blue swapped it).
	// I haven't confirmed that it's correct.
	static const u32 pal_part1[8] = {
		0x000000,0x800000,0x008000,0x808000,0x000080,0x800080,0x008080,0xc0c0c0
	};
	static const u32 pal_part2[8] = {
		0x808080,0xff0000,0x00ff00,0xffff00,0x0000ff,0xff00ff,0x00ffff,0xffffff
	};

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

			palent = de_getbyte(fpos+j*rowspan+i);
			if(palent<8) {
				clr = pal_part1[palent];
			}
			else if(palent>=248) {
				clr = pal_part2[palent-248];
			}
			else {
				clr = DE_MAKE_RGB(254,palent,254); // Just an arbitrary color
				badcolorflag = 1;
			}
			de_bitmap_setpixel_rgb(img, i, j, clr);
		}
	}
	if(badcolorflag) {
		de_warn(c, "Image uses nonportable colors");
	}
}
Exemple #8
0
static void do_decode_image_default(deark *c, lctx *d, struct tgaimginfo *imginfo, dbuf *unc_pixels,
	de_finfo *fi, unsigned int createflags)
{
	de_bitmap *img = NULL;
	i64 i, j;
	u8 b;
	u32 clr;
	u8 a;
	i64 rowspan;
	int output_bypp;
	unsigned int getrgbflags;
	i64 interleave_stride;
	i64 interleave_pass;
	i64 cur_rownum; // 0-based, does not account for bottom-up orientation

	if(d->pixel_depth==1) {
		de_warn(c, "1-bit TGA images are not portable, and may not be decoded correctly");
		rowspan = (imginfo->width+7)/8;
	}
	else {
		rowspan = imginfo->width*d->bytes_per_pixel;
	}

	if(d->color_type==TGA_CLRTYPE_GRAYSCALE || d->pixel_depth==1)
		output_bypp=1;
	else
		output_bypp=3;

	if(d->has_alpha_channel)
		output_bypp++;

	if(d->file_format==FMT_VST)
		getrgbflags = 0;
	else
		getrgbflags = DE_GETRGBFLAG_BGR;

	img = de_bitmap_create(c, imginfo->width, imginfo->height, output_bypp);

	switch(d->interleave_mode) {
	case 1: interleave_stride = 2; break;
	case 2: interleave_stride = 4; break;
	default: interleave_stride = 1;
	}

	cur_rownum = 0;
	interleave_pass = 0;

	for(j=0; j<imginfo->height; j++) {
		i64 j_adj;

		if(d->top_down)
			j_adj = cur_rownum;
		else
			j_adj = imginfo->height-1-cur_rownum;

		// Update the row number for next time
		cur_rownum += interleave_stride;
		if(cur_rownum >= imginfo->height) {
			// Went past the end of the image; move back to near the start.
			interleave_pass++;
			cur_rownum = interleave_pass;
		}

		for(i=0; i<imginfo->width; i++) {
			i64 i_adj;

			if(d->right_to_left)
				i_adj = imginfo->width-1-i;
			else
				i_adj = i;

			if(d->pixel_depth==1) {
				de_convert_row_bilevel(unc_pixels, j*rowspan, img, j_adj, 0);
			}
			else if(d->color_type==TGA_CLRTYPE_TRUECOLOR && (d->pixel_depth==15 || d->pixel_depth==16)) {
				clr = (u32)dbuf_getu16le(unc_pixels, j*rowspan + i*d->bytes_per_pixel);
				clr = de_rgb555_to_888(clr);
				de_bitmap_setpixel_rgb(img, i_adj, j_adj, clr);
			}
			else if(d->color_type==TGA_CLRTYPE_TRUECOLOR) {
				clr = dbuf_getRGB(unc_pixels, j*rowspan + i*d->bytes_per_pixel, getrgbflags);
				if(d->has_alpha_channel) {
					a = dbuf_getbyte(unc_pixels, j*rowspan + i*d->bytes_per_pixel+3);
					de_bitmap_setpixel_rgba(img, i_adj, j_adj, DE_SET_ALPHA(clr, a));
				}
				else {
					de_bitmap_setpixel_rgb(img, i_adj, j_adj, clr);
				}
			}
			else if(d->color_type==TGA_CLRTYPE_GRAYSCALE) {
				b = dbuf_getbyte(unc_pixels, j*rowspan + i*d->bytes_per_pixel);
				de_bitmap_setpixel_gray(img, i_adj, j_adj, b);
			}
			else if(d->color_type==TGA_CLRTYPE_PALETTE) {
				b = dbuf_getbyte(unc_pixels, j*rowspan + i*d->bytes_per_pixel);
				de_bitmap_setpixel_rgb(img, i_adj, j_adj, d->pal[(unsigned int)b]);
			}
		}
	}

	de_bitmap_write_to_file_finfo(img, fi, createflags);

	de_bitmap_destroy(img);
}