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); }
static int do_read_palette(deark *c, lctx *d, i64 pos) { i64 i; i64 idx; unsigned int getrgbflags; if(d->color_type != TGA_CLRTYPE_PALETTE) { return 1; // don't care about the palette } if(d->cmap_depth != 24) { de_err(c, "Palettes with depth=%d are not supported.", (int)d->cmap_depth); return 0; } if(d->pixel_depth != 8) { de_err(c, "Paletted images with depth=%d are not supported.", (int)d->pixel_depth); return 0; } if(d->file_format==FMT_VST) getrgbflags = 0; else getrgbflags = DE_GETRGBFLAG_BGR; for(i=0; i<d->cmap_length; i++) { idx = d->cmap_start + i; if(idx<0 || idx>255) continue; d->pal[idx] = dbuf_getRGB(c->infile, pos + i*d->bytes_per_pal_entry, getrgbflags); de_dbg_pal_entry(c, idx, d->pal[idx]); } return 1; }
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); }
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); }