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); }
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); }