Esempio n. 1
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);
}
Esempio n. 2
0
static void do_image_16_32bit(deark *c, lctx *d, dbuf *bits, de_int64 bits_offset)
{
	struct deark_bitmap *img = NULL;
	de_int64 i, j;
	int has_transparency;
	de_uint32 v;
	de_int64 k;
	de_byte sm[4];

	if(d->bitfields_type==BF_SEGMENT) {
		has_transparency = (d->bitfields_segment_len>=16 && d->bitfield[3].mask!=0);
	}
	else if(d->bitfields_type==BF_IN_HEADER) {
		has_transparency = (d->bitfield[3].mask!=0);
	}
	else {
		has_transparency = 0;
	}

	img = bmp_bitmap_create(c, d, has_transparency?4:3);
	for(j=0; j<d->height; j++) {
		for(i=0; i<d->width; i++) {
			if(d->bitcount==16) {
				v = (de_uint32)dbuf_getui16le(bits, bits_offset + j*d->rowspan + 2*i);
			}
			else {
				v = (de_uint32)dbuf_getui32le(bits, bits_offset + j*d->rowspan + 4*i);
			}

			for(k=0; k<4; k++) {
				if(d->bitfield[k].mask!=0) {
					sm[k] = (de_byte)(0.5 + d->bitfield[k].scale * (double)((v&d->bitfield[k].mask) >> d->bitfield[k].shift));
				}
				else {
					if(k==3)
						sm[k] = 255; // Default alpha sample = opaque
					else
						sm[k] = 0; // Default other samples = 0
				}
			}
			de_bitmap_setpixel_rgba(img, i, j, DE_MAKE_RGBA(sm[0], sm[1], sm[2], sm[3]));
		}
Esempio n. 3
0
static void do_decode_1_4_8bit(deark *c, lctx *d, struct page_ctx *pg)
{
	struct deark_bitmap *img = NULL;
	de_int64 i, j;
	de_byte a, b;
	de_byte x;
	de_int32 fgcol;

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

	for(j=0; j<pg->type_info->height; j++) {
		for(i=0; i<pg->type_info->width; i++) {
			// Foreground
			b = de_get_bits_symbol(c->infile, pg->type_info->bpp, pg->image_pos + pg->rowspan*j, i);

			if(pg->type_info->bpp==8) {
				fgcol = getpal256((int)b);
			}
			else if(pg->type_info->bpp==4) {
				fgcol = pal16[(unsigned int)b];
			}
			else {
				fgcol = b ? 0x0000000 : 0xffffff;
			}

			// Opacity
			if(pg->mask_pos) {
				x = de_get_bits_symbol(c->infile, 1, pg->mask_pos + pg->mask_rowspan*j, i);
				a = x ? 0xff : 0x00;
			}
			else {
				a = 0xff;
			}
			de_bitmap_setpixel_rgba(img, i, j, DE_SET_ALPHA(fgcol, a));
		}
	}

	de_bitmap_write_to_file(img, pg->filename_token, 0);
	de_bitmap_destroy(img);
}
Esempio n. 4
0
File: tga.c Progetto: jsummers/deark
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);
}
Esempio n. 5
0
// Paint a character at the given index in the given font, to the given bitmap.
void de_font_paint_character_idx(deark *c, de_bitmap *img,
	struct de_bitmap_font *font, i64 char_idx,
	i64 xpos, i64 ypos, u32 fgcol, u32 bgcol,
	unsigned int flags)
{
	i64 i, j;
	i64 i_src; // -1 = No source position
	i64 j_src;
	u8 x;
	int fg;
	u32 clr;
	struct de_bitmap_font_char *ch;
	i64 num_x_pixels_to_paint;
	int vga9col_flag = 0;

	if(char_idx<0 || char_idx>=font->num_chars) return;
	ch = &font->char_array[char_idx];
	if(!is_valid_char(ch)) return;
	if(ch->width > font->nominal_width) return;
	if(ch->height > font->nominal_height) return;

	num_x_pixels_to_paint = (i64)ch->extraspace_l + (i64)ch->width + (i64)ch->extraspace_r;
	if((flags&DE_PAINTFLAG_VGA9COL) && ch->width==8) {
		vga9col_flag = 1;
		num_x_pixels_to_paint = 9;
	}

	for(j=0; j<ch->height; j++) {
		j_src = j;
		if(flags&DE_PAINTFLAG_TOPHALF) {
			j_src = j/2;
		}
		else if(flags&DE_PAINTFLAG_BOTTOMHALF) {
			j_src = (ch->height+j)/2;
		}

		for(i=0; i<num_x_pixels_to_paint; i++) {
			i_src = i;
			if(flags&DE_PAINTFLAG_LEFTHALF) {
				i_src = i/2;
			}
			else if(flags&DE_PAINTFLAG_RIGHTHALF) {
				i_src = (num_x_pixels_to_paint+i)/2;
			}

			if(i_src==8 && vga9col_flag) {
				// Manufacture a column 8.
				if(ch->codepoint_nonunicode>=0xb0 && ch->codepoint_nonunicode<=0xdf) {
					i_src = 7; // Make this pixel a duplicate of the one in col #7.
				}
				else {
					i_src = -1; // Make this pixel a background pixel.
				}
			}

			i_src -= (i64)ch->extraspace_l;

			if(i_src>=0 && i_src<ch->width) {
				x = ch->bitmap[j_src*ch->rowspan + i_src/8];
				fg = (x & (1<<(7-i_src%8))) ? 1 : 0;
			}
			else {
				fg = 0;
			}

			if(fg || !(flags&DE_PAINTFLAG_TRNSBKGD)) {
				clr = fg ? fgcol : bgcol;
				de_bitmap_setpixel_rgba(img, xpos+i, ypos+ch->v_offset+j, clr);
			}
		}
	}
}