// Rasterized caption static void handle_2_125(deark *c, lctx *d, const struct ds_info *dsi, de_int64 pos, de_int64 len) { dbuf *unc_pixels = NULL; struct deark_bitmap *img = NULL; de_int64 i, j; de_byte b; de_int64 rowspan; de_int64 width, height; // I can't find any examples of this field, so this may not be correct. // The format seems to be well-documented, though the pixels are in an // unusual order. unc_pixels = dbuf_open_input_subfile(c->infile, pos, len); width = 460; height = 128; img = de_bitmap_create(c, width, height, 1); rowspan = height/8; for(j=0; j<width; j++) { for(i=0; i<height; i++) { b = de_get_bits_symbol(unc_pixels, 1, rowspan*j, i); de_bitmap_setpixel_gray(img, j, (height-1-i), b?0:255); } } de_bitmap_write_to_file(img, "caption", DE_CREATEFLAG_IS_AUX); de_bitmap_destroy(img); dbuf_close(unc_pixels); }
static void do_decode_thumbnail(deark *c, lctx *d) { dbuf *unc_pixels = NULL; i64 hdrsize = 2; de_dbg(c, "thumbnail image at %d", (int)d->thumbnail_offset); de_dbg_indent(c, 1); // The thumbnail image is supposed to use the same format as the main image, // except without compression. (And the dimensions are obviously different.) // Presumably this means the origin, palette, etc. will be the same. // But based on the few TGA thumbnails we've seen, nobody reads the spec, and // it's anybody's guess what format the thumbnail will use. // TGA 2.0 spec says the dimensions are one *byte* each. d->thumbnail_image.width = (i64)de_getbyte(d->thumbnail_offset); d->thumbnail_image.height = (i64)de_getbyte(d->thumbnail_offset+1); de_dbg(c, "thumbnail dimensions: %d"DE_CHAR_TIMES"%d", (int)d->thumbnail_image.width, (int)d->thumbnail_image.height); if(d->thumbnail_image.width!=0 && d->thumbnail_image.height==0) { de_warn(c, "Thumbnail image height is 0. Assuming the file incorrectly uses " "16-bit thumbnail dimensions, instead of 8."); d->thumbnail_image.width = de_getu16le(d->thumbnail_offset); d->thumbnail_image.height = de_getu16le(d->thumbnail_offset+2); de_dbg(c, "revised thumbnail dimensions: %d"DE_CHAR_TIMES"%d", (int)d->thumbnail_image.width, (int)d->thumbnail_image.height); hdrsize = 4; } if(!de_good_image_dimensions(c, d->thumbnail_image.width, d->thumbnail_image.height)) goto done; d->thumbnail_image.img_size_in_bytes = d->thumbnail_image.height * d->thumbnail_image.width * d->bytes_per_pixel; unc_pixels = dbuf_open_input_subfile(c->infile, d->thumbnail_offset+hdrsize, d->thumbnail_image.img_size_in_bytes); do_decode_image(c, d, &d->thumbnail_image, unc_pixels, "thumb", DE_CREATEFLAG_IS_AUX); done: dbuf_close(unc_pixels); de_dbg_indent(c, -1); }
void de_run(deark *c) { dbuf *orig_ifile = NULL; dbuf *subfile = NULL; de_int64 subfile_size; struct deark_module_info *module_to_use = NULL; const char *friendly_infn; if(c->modhelp_req && c->input_format_req) { do_modhelp(c); goto done; } if(c->input_style==DE_INPUTSTYLE_STDIN) { friendly_infn = "[stdin]"; } else { friendly_infn = c->input_filename; } if(!friendly_infn) { de_err(c, "Input file not set\n"); de_fatalerror(c); return; } de_register_modules(c); if(c->input_format_req) { module_to_use = de_get_module_by_id(c, c->input_format_req); if(!module_to_use) { de_err(c, "Unknown module \"%s\"\n", c->input_format_req); goto done; } } if(c->slice_size_req_valid) { de_dbg(c, "Input file: %s[%d,%d]\n", friendly_infn, (int)c->slice_start_req, (int)c->slice_size_req); } else if(c->slice_start_req) { de_dbg(c, "Input file: %s[%d]\n", friendly_infn, (int)c->slice_start_req); } else { de_dbg(c, "Input file: %s\n", friendly_infn); } if(c->input_style==DE_INPUTSTYLE_STDIN) { orig_ifile = dbuf_open_input_stdin(c, c->input_filename); } else { orig_ifile = dbuf_open_input_file(c, c->input_filename); } if(!orig_ifile) { goto done; } c->infile = orig_ifile; // If we are only supposed to look at a segment of the original file, // do that by creating a child dbuf, using dbuf_open_input_subfile(). if(c->slice_start_req>0 || c->slice_size_req_valid) { if(c->slice_size_req_valid) subfile_size = c->slice_size_req; else subfile_size = dbuf_get_length(c->infile) - c->slice_start_req; subfile = dbuf_open_input_subfile(c->infile, c->slice_start_req, subfile_size); c->infile = subfile; } if(!module_to_use) { module_to_use = detect_module_for_file(c); } if(!module_to_use) { if(c->infile->len==0) de_err(c, "Unknown or unsupported file format (empty file)\n"); else de_err(c, "Unknown or unsupported file format\n"); goto done; } de_msg(c, "Module: %s\n", module_to_use->id); if(module_to_use->flags&DE_MODFLAG_NONWORKING) { de_warn(c, "The %s module is considered to be incomplete, and may " "not work properly. Caveat emptor.\n", module_to_use->id); } de_dbg2(c, "file size: %" INT64_FMT "\n", c->infile->len); if(!de_run_module(c, module_to_use, NULL)) { goto done; } // The DE_MODFLAG_NOEXTRACT flag means the module is not expected to extract // any files. if(c->num_files_extracted==0 && c->error_count==0 && !(module_to_use->flags&DE_MODFLAG_NOEXTRACT)) { de_msg(c, "No files found to extract!\n"); } done: if(subfile) dbuf_close(subfile); if(orig_ifile) dbuf_close(orig_ifile); }
static void de_run_tga(deark *c, de_module_params *mparams) { lctx *d = NULL; i64 pos; dbuf *unc_pixels = NULL; int saved_indent_level; i64 rowspan_tmp; de_dbg_indent_save(c, &saved_indent_level); d = de_malloc(c, sizeof(lctx)); detect_file_format(c, d); if(d->file_format==FMT_VST) { de_declare_fmt(c, "TrueVista"); } else { de_declare_fmt(c, "TGA"); } pos = 0; if(d->file_format==FMT_VST) { if(!do_read_vst_headers(c, d)) goto done; } else { if(!do_read_tga_headers(c, d)) goto done; } pos += 18; if(d->id_field_len>0) { de_dbg(c, "image ID at %d (len=%d)", (int)pos, (int)d->id_field_len); pos += d->id_field_len; } if(d->color_map_type!=0) { d->bytes_per_pal_entry = (d->cmap_depth+7)/8; d->pal_size_in_bytes = d->cmap_length * d->bytes_per_pal_entry; de_dbg(c, "color map at %d (%d colors, %d bytes)", (int)pos, (int)d->cmap_length, (int)d->pal_size_in_bytes); de_dbg_indent(c, 1); if(!do_read_palette(c, d, pos)) goto done; de_dbg_indent(c, -1); pos += d->pal_size_in_bytes; } de_dbg(c, "bitmap at %d", (int)pos); de_dbg_indent(c, 1); d->bytes_per_pixel = ((d->pixel_depth+7)/8); if(d->pixel_depth==1) { rowspan_tmp = (d->main_image.width+7)/8; } else { rowspan_tmp = d->main_image.width * d->bytes_per_pixel; } d->main_image.img_size_in_bytes = d->main_image.height * rowspan_tmp; if(d->color_type!=TGA_CLRTYPE_PALETTE && d->color_type!=TGA_CLRTYPE_TRUECOLOR && d->color_type!=TGA_CLRTYPE_GRAYSCALE) { de_err(c, "Unsupported color type (%d: %s)", (int)d->color_type, d->clrtype_name); goto done; } if( (d->color_type==TGA_CLRTYPE_PALETTE && d->pixel_depth==8) || (d->color_type==TGA_CLRTYPE_TRUECOLOR && d->pixel_depth==15) || (d->color_type==TGA_CLRTYPE_TRUECOLOR && d->pixel_depth==16) || (d->color_type==TGA_CLRTYPE_TRUECOLOR && d->pixel_depth==24) || (d->color_type==TGA_CLRTYPE_TRUECOLOR && d->pixel_depth==32) || (d->color_type==TGA_CLRTYPE_GRAYSCALE && d->pixel_depth==1) || (d->color_type==TGA_CLRTYPE_GRAYSCALE && d->pixel_depth==8) ) { ; } else { de_err(c, "Unsupported TGA image type (%s, depth=%d)", d->clrtype_name, (int)d->pixel_depth); goto done; } if(d->cmpr_type==TGA_CMPR_RLE) { if(d->pixel_depth<8) { de_err(c, "RLE compression not supported when depth (%d) is less than 8", (int)d->pixel_depth); goto done; } unc_pixels = dbuf_create_membuf(c, d->main_image.img_size_in_bytes, 1); if(!do_decode_rle(c, d, pos, unc_pixels)) goto done; } else if(d->cmpr_type==TGA_CMPR_NONE) { unc_pixels = dbuf_open_input_subfile(c->infile, pos, d->main_image.img_size_in_bytes); } else { de_err(c, "Unsupported compression type (%d, %s)", (int)d->cmpr_type, d->cmpr_name); goto done; } // Maybe scan the image, to help detect transparency. do_prescan_image(c, d, unc_pixels); if(d->pixel_depth==32) { de_dbg(c, "using alpha channel: %s", d->has_alpha_channel?"yes":"no"); } // TODO: 16-bit images could theoretically have a transparency bit, but I don't // know how to detect that. do_decode_image(c, d, &d->main_image, unc_pixels, NULL, 0); de_dbg_indent(c, -1); if(d->thumbnail_offset!=0) { do_decode_thumbnail(c, d); } done: dbuf_close(unc_pixels); de_dbg_indent_restore(c, saved_indent_level); de_free(c, d); }
static void de_run_alphabmp(deark *c, de_module_params *mparams) { unsigned int flags; lctx *d = NULL; i64 pos; i64 palsize; dbuf *unc_pixels = NULL; int saved_indent_level; de_dbg_indent_save(c, &saved_indent_level); d = de_malloc(c, sizeof(lctx)); de_declare_fmt(c, "Alpha Microsystems BMP"); pos = 10; de_dbg(c, "bitmap image definition block at %d", (int)pos); de_dbg_indent(c, 1); d->w = de_getu16le(pos); d->h = de_getu16le(pos+2); de_dbg_dimensions(c, d->w, d->h); if(!de_good_image_dimensions(c, d->w, d->h)) goto done; d->bpp = de_getu16le(pos+4); de_dbg(c, "bits/pixel: %d", (int)d->bpp); flags = (unsigned int)de_getu16le(pos+6); d->has_palette = flags & 0x01; d->palette_is_hls = (flags>>1) & 0x01; de_dbg(c, "has-palette: %d", (int)d->has_palette); if(d->has_palette) de_dbg(c, "palette-is-HLS: %d", (int)d->palette_is_hls); d->compression = de_getu16le(pos+8); de_dbg(c, "compression: %d", (int)d->compression); de_dbg_indent(c, -1); pos += 70; if(d->has_palette) { if(d->palette_is_hls && d->bpp<=8) { de_err(c, "HLS palettes are not supported"); goto done; } if(!do_read_palette(c, d, pos, &palsize)) goto done; pos += palsize; } else if(d->bpp<=8) { de_err(c, "Paletted images without an embedded palette are not supported"); goto done; } de_dbg(c, "bitmap at %d", (int)pos); de_dbg_indent(c, 1); if(d->compression) { unc_pixels = dbuf_create_membuf(c, 32768, 0); if(!do_uncompress_image(c, d, pos, unc_pixels)) goto done; } else { unc_pixels = dbuf_open_input_subfile(c->infile, pos, c->infile->len - pos); } if(d->bpp!=1 && d->bpp!=4 && d->bpp!=8 && d->bpp!=24) { de_err(c, "%d bits/pixel is not supported", (int)d->bpp); goto done; } do_bitmap(c, d, unc_pixels); de_dbg_indent(c, -1); done: de_dbg_indent_restore(c, saved_indent_level); dbuf_close(unc_pixels); de_free(c, d); }