static void de_run_gzip(deark *c, de_module_params *mparams) { lctx *d = NULL; i64 pos; i64 member_size; d = de_malloc(c, sizeof(lctx)); d->crco = de_crcobj_create(c, DE_CRCOBJ_CRC32_IEEE); pos = 0; while(1) { if(pos >= c->infile->len) break; if(!do_gzip_read_member(c, d, pos, &member_size)) { break; } if(member_size<=0) break; pos += member_size; } dbuf_close(d->output_file); if(d) { de_crcobj_destroy(d->crco); de_free(c, d); } }
static void do_read_bitmap(deark *c, lctx *d, de_int64 pos) { de_int64 ver_num; dbuf *unc_pixels = NULL; ver_num = de_getui32be(pos); de_dbg(c, "version number: %u\n", (unsigned int)ver_num); if(ver_num!=0 && ver_num!=2 && ver_num!=3) { de_warn(c, "Unrecognized version number: %u\n", (unsigned int)ver_num); } pos += 512; unc_pixels = dbuf_create_membuf(c, MACPAINT_IMAGE_BYTES, 1); de_fmtutil_uncompress_packbits(c->infile, pos, c->infile->len - pos, unc_pixels, NULL); if(unc_pixels->len < MACPAINT_IMAGE_BYTES) { de_warn(c, "Image decompressed to %d bytes, expected %d.\n", (int)unc_pixels->len, (int)MACPAINT_IMAGE_BYTES); } de_convert_and_write_image_bilevel(unc_pixels, 0, MACPAINT_WIDTH, MACPAINT_HEIGHT, MACPAINT_WIDTH/8, DE_CVTF_WHITEISZERO, NULL, 0); dbuf_close(unc_pixels); }
static void do_extract_file(deark *c, lctx *d, de_int64 dir_pos, de_byte filetype_c64s, de_byte filetype) { de_int64 load_addr; de_int64 end_addr; de_int64 offset; dbuf *f = NULL; de_int64 payload_size; // = file_size-2 de_ucstring *fname = NULL; de_int64 fname_len; de_int64 i; de_int64 fnpos; de_finfo *fi = NULL; load_addr = de_getui16le(dir_pos+2); end_addr = de_getui16le(dir_pos+4); offset = de_getui32le(dir_pos+8); de_dbg(c, "load_addr=%d end_addr=%d offset=%d\n", (int)load_addr, (int)end_addr, (int)offset); // File name at pos+16 fnpos = dir_pos+16; // Find the length of the (space-padded) filename. fname_len = 0; for(i=15; i>=0; i--) { if(de_getbyte(fnpos+i)!=' ') { fname_len = i+1; break; } } de_dbg2(c, "filename length: %d\n", (int)fname_len); fname = ucstring_create(c); dbuf_read_to_ucstring(c->infile, fnpos, fname_len, fname, 0, DE_ENCODING_PETSCII); de_dbg(c, "filename: \"%s\"\n", ucstring_get_printable_sz(fname)); ucstring_append_sz(fname, ".prg", DE_ENCODING_ASCII); fi = de_finfo_create(c); de_finfo_set_name_from_ucstring(c, fi, fname); fi->original_filename_flag = 1; payload_size = end_addr - load_addr; if(payload_size < 0) { // TODO: Try to support files that don't have end_addr set properly. de_err(c, "This type of T64 file is not supported.\n"); goto done; } f = dbuf_create_output_file(c, NULL, fi, 0); dbuf_copy(c->infile, dir_pos+2, 2, f); dbuf_copy(c->infile, offset, payload_size, f); done: dbuf_close(f); de_finfo_destroy(c, fi); ucstring_destroy(fname); }
static void do_html_end(deark *c, lctx *d) { if(!d->html_outf) return; dbuf_puts(d->html_outf, "</body>\n</html>\n"); dbuf_close(d->html_outf); d->html_outf = NULL; }
// 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); }
int dbuf_create_file_from_slice(dbuf *inf, i64 pos, i64 data_size, const char *ext, de_finfo *fi, unsigned int createflags) { dbuf *f; f = dbuf_create_output_file(inf->c, ext, fi, createflags); if(!f) return 0; dbuf_copy(inf, pos, data_size, f); dbuf_close(f); return 1; }
static int do_gem_img(deark *c, lctx *d) { dbuf *unc_pixels = NULL; de_bitmap *img = NULL; de_finfo *fi = NULL; int is_color = 0; i64 k; if(d->header_size_in_words==9 && (d->nplanes==3 || d->nplanes==4)) { i64 x; x = de_getu16be(8*2); if(x==0) { is_color = 1; } } de_dbg(c, "image at %d", (int)d->header_size_in_bytes); unc_pixels = dbuf_create_membuf(c, d->rowspan_total*d->h, 0); uncompress_pixels(c, d, unc_pixels, d->header_size_in_bytes, c->infile->len-d->header_size_in_bytes); img = de_bitmap_create(c, d->w, d->h, is_color?3:1); fi = de_finfo_create(c); set_density(c, d, fi); if(d->nplanes==1) { de_convert_image_bilevel(unc_pixels, 0, d->rowspan_per_plane, img, DE_CVTF_WHITEISZERO); } else if(is_color && d->nplanes==3) { for(k=0; k<8; k++) { d->pal[k] = pal3bit[k]; } read_paletted_image(c, d, unc_pixels, img); } else if(is_color && d->nplanes==4) { for(k=0; k<16; k++) { d->pal[k] = pal4bit[k]; } read_paletted_image(c, d, unc_pixels, img); } else { de_make_grayscale_palette(d->pal, ((i64)1)<<((unsigned int)d->nplanes), 1); read_paletted_image(c, d, unc_pixels, img); } de_bitmap_write_to_file_finfo(img, fi, 0); de_bitmap_destroy(img); de_finfo_destroy(c, fi); dbuf_close(unc_pixels); return 1; }
static void handler_iccp(deark *c, lctx *d, struct handler_params *hp) { u8 cmpr_type; dbuf *f = NULL; struct de_stringreaderdata *prof_name_srd = NULL; de_finfo *fi = NULL; char prof_name2[100]; size_t prof_name2_strlen; i64 pos = hp->dpos; prof_name_srd = dbuf_read_string(c->infile, pos, 80, 80, DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_LATIN1); if(!prof_name_srd->found_nul) goto done; de_dbg(c, "profile name: \"%s\"", ucstring_getpsz_d(prof_name_srd->str)); pos += prof_name_srd->bytes_consumed; // Our working copy, to use as part of the filename. de_strlcpy(prof_name2, prof_name_srd->sz, sizeof(prof_name2)); if(!de_strcasecmp(prof_name2, "icc") || !de_strcasecmp(prof_name2, "icc profile")) { prof_name2[0] = '\0'; // Ignore generic name. } prof_name2_strlen = de_strlen(prof_name2); if(prof_name2_strlen>=5) { if(de_sz_has_ext(prof_name2, "icc")) { // If the name already ends in ".icc", chop it off so that we don't end // up with a double ".icc.icc" file extension. prof_name2[prof_name2_strlen-4] = '\0'; } } cmpr_type = de_getbyte_p(&pos); if(cmpr_type!=0) return; fi = de_finfo_create(c); if(c->filenames_from_file && prof_name2[0]) de_finfo_set_name_from_sz(c, fi, prof_name2, 0, DE_ENCODING_LATIN1); f = dbuf_create_output_file(c, "icc", fi, DE_CREATEFLAG_IS_AUX); de_decompress_deflate(c->infile, pos, hp->dlen - pos, f, 0, NULL, d->is_CgBI ? 0 : DE_DEFLATEFLAG_ISZLIB); done: dbuf_close(f); de_finfo_destroy(c, fi); de_destroy_stringreaderdata(c, prof_name_srd); }
static void destroy_bitstream(deark *c, lctx *d, struct stream_info *si) { if(!si) return; if((si->stream_type==STREAMTYPE_VORBIS || si->stream_type==STREAMTYPE_THEORA) && si->stream_state==0) { do_theora_vorbis_after_headers(c, d, si); } if(si->header_stream) { dbuf_close(si->header_stream); } de_free(c, si); }
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); }
static void uncompress_pixels(deark *c, lctx *d, dbuf *unc_pixels, i64 pos1, i64 len) { i64 bytes_consumed; i64 pos; i64 ypos; i64 repeat_count; i64 k; i64 plane; dbuf *unc_line = NULL; d->pattern_buf = de_malloc(c, d->patlen); unc_line = dbuf_create_membuf(c, d->rowspan_total, 0); pos = pos1; ypos = 0; while(1) { if(ypos >= d->h) break; repeat_count = 1; dbuf_empty(unc_line); for(plane=0; plane<d->nplanes; plane++) { uncompress_line(c, d, unc_line, pos, ypos, &bytes_consumed, &repeat_count); pos+=bytes_consumed; if(bytes_consumed<1) goto done1; } for(k=0; k<repeat_count; k++) { if(ypos >= d->h) break; dbuf_copy(unc_line, 0, d->rowspan_total, unc_pixels); ypos++; } } done1: dbuf_close(unc_line); de_free(c, d->pattern_buf); d->pattern_buf = NULL; }
static void do_theora_vorbis_after_headers(deark *c, lctx *d, struct stream_info *si) { i64 pos = 0; int saved_indent_level; dbuf *f = NULL; de_dbg_indent_save(c, &saved_indent_level); if(si->stream_state!=0) goto done; if(!si->header_stream) goto done; if(!si->sti) goto done; f = si->header_stream; de_dbg(c, "[decoding %s comment/setup headers, %d bytes]", si->sti->name, (int)si->header_stream->len); de_dbg_indent(c, 1); // Make sure the comment header signature is present. if(si->stream_type==STREAMTYPE_VORBIS) { if(dbuf_memcmp(f, 0, "\x03" "vorbis", 7)) { goto done; } pos += 7; } else if(si->stream_type==STREAMTYPE_THEORA) { if(dbuf_memcmp(f, 0, "\x81" "theora", 7)) { goto done; } pos += 7; } do_vorbis_comment_block(c, d, f, pos); // TODO: "Setup" header done: si->stream_state = 1; dbuf_close(si->header_stream); si->header_stream = NULL; de_dbg_indent_restore(c, saved_indent_level); }
static void de_run_gzip(deark *c, de_module_params *mparams) { lctx *d = NULL; de_int64 pos; de_int64 member_size; d = de_malloc(c, sizeof(lctx)); pos = 0; while(1) { if(pos >= c->infile->len) break; if(!do_gzip_read_member(c, d, pos, &member_size)) { break; } if(member_size<=0) break; pos += member_size; } dbuf_close(d->output_file); de_free(c, d); }
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); }
// Caption/abstract static void handle_2_120(deark *c, lctx *d, const struct ds_info *dsi, de_int64 pos, de_int64 len) { de_ucstring *s = NULL; dbuf *outf = NULL; int encoding; const char *fntoken; if(c->extract_level<2) { handle_text(c, d, dsi, pos, len); goto done; } // FIXME: There is currently no way to extract IPTC captions to files, // except when reading a raw IPTC file. If IPTC is embedded in some other // file (as it usually is), then the -a option will extract the entire // IPTC data, and we will never get here. fntoken = "caption.txt"; encoding = get_ds_encoding(c, d, dsi->recnum); if(encoding==DE_ENCODING_UNKNOWN) { // If the encoding is unknown, copy the raw bytes. dbuf_create_file_from_slice(c->infile, pos, len, fntoken, NULL, DE_CREATEFLAG_IS_AUX); goto done; } // If the encoding is known, convert to UTF-8. s = ucstring_create(c); dbuf_read_to_ucstring(c->infile, pos, len, s, 0, encoding); outf = dbuf_create_output_file(c, fntoken, NULL, DE_CREATEFLAG_IS_AUX); ucstring_write_as_utf8(c, s, outf, 1); done: if(outf) dbuf_close(outf); if(s) ucstring_destroy(s); }
// Read and process the keyword, language, translated keyword, or main text // field of a tEXt/zTXt/iTXt chunk. // 'bytes_consumed' does not include the NUL separator/terminator. // This is a wrapper that first decompresses the field if necessary. static int do_text_field(deark *c, lctx *d, struct text_chunk_ctx *tcc, int which_field, i64 pos, i64 bytes_avail, int is_nul_terminated, int is_compressed, int encoding, i64 *bytes_consumed) { dbuf *tmpdbuf = NULL; int retval = 0; i64 bytes_consumed2; if(!is_compressed) { retval = do_unc_text_field(c, d, tcc, which_field, c->infile, pos, bytes_avail, is_nul_terminated, encoding, bytes_consumed); goto done; } // Decompress to a membuf, then call do_unc_text_field() with that membuf. // Note that a compressed field cannot be NUL-terminated. *bytes_consumed = bytes_avail; tmpdbuf = dbuf_create_membuf(c, 0, 0); if(!de_decompress_deflate(c->infile, pos, bytes_avail, tmpdbuf, 0, NULL, d->is_CgBI ? 0 : DE_DEFLATEFLAG_ISZLIB)) { goto done; } retval = do_unc_text_field(c, d, tcc, which_field, tmpdbuf, 0, tmpdbuf->len, 0, encoding, &bytes_consumed2); done: dbuf_close(tmpdbuf); return retval; }
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); }
// XIMG and similar formats. // TODO: Should this function be merged with do_gem_img()? static int do_gem_ximg(deark *c, lctx *d) { dbuf *unc_pixels = NULL; de_bitmap *img = NULL; de_finfo *fi = NULL; int retval = 0; int saved_indent_level; de_dbg_indent_save(c, &saved_indent_level); de_dbg(c, "header (continued) at %d", 8*2); de_dbg_indent(c, 1); if((d->nplanes>=1 && d->nplanes<=8) /* || d->nplanes==24 */) { ; } else { if(d->is_ximg) de_err(c, "%d-plane XIMG images are not supported", (int)d->nplanes); else de_err(c, "This type of %d-plane image is not supported", (int)d->nplanes); goto done; } if(d->header_size_in_words==25 && !d->is_ximg) { i64 pal_pos = d->header_size_in_bytes-32; de_dbg(c, "palette at %d", (int)pal_pos); de_dbg_indent(c, 1); de_fmtutil_read_atari_palette(c, c->infile, pal_pos, d->pal, 16, ((i64)1)<<d->nplanes, 0); de_dbg_indent(c, -1); } else { read_palette_ximg(c, d); } if(d->nplanes==1 && d->pal[0]==d->pal[1]) { de_dbg(c, "Palette doesn't seem to be present. Using a default palette."); d->pal[0] = DE_STOCKCOLOR_WHITE; d->pal[1] = DE_STOCKCOLOR_BLACK; } de_dbg_indent(c, -1); de_dbg(c, "image at %d", (int)d->header_size_in_bytes); unc_pixels = dbuf_create_membuf(c, d->rowspan_total*d->h, 0); uncompress_pixels(c, d, unc_pixels, d->header_size_in_bytes, c->infile->len-d->header_size_in_bytes); img = de_bitmap_create(c, d->w, d->h, 3); fi = de_finfo_create(c); set_density(c, d, fi); if(d->nplanes>8) { read_rgb_image(c, d, unc_pixels, img); } else { read_paletted_image(c, d, unc_pixels, img); } de_bitmap_write_to_file_finfo(img, fi, 0); retval = 1; done: de_bitmap_destroy(img); de_finfo_destroy(c, fi); dbuf_close(unc_pixels); de_dbg_indent_restore(c, saved_indent_level); return retval; }
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); }
// Generic (ImageMagick?) profile. Hex-encoded, with three header lines. static void on_im_generic_profile_main(deark *c, lctx *d, struct text_chunk_ctx *tcc, dbuf *inf, i64 pos1, i64 len) { int k; i64 pos = pos1; i64 dlen; int dump_to_file = 0; int decode_to_membuf = 0; const char *ext = NULL; // Skip the first three lines for(k=0; k<3; k++) { int ret; i64 foundpos = 0; ret = dbuf_search_byte(inf, 0x0a, pos, pos1+len-pos, &foundpos); if(!ret) goto done; pos = foundpos+1; } dlen = pos1+len-pos; if(tcc->im_generic_profile_type==PROFILETYPE_XMP) { dump_to_file = 1; ext = "xmp"; } else if(tcc->im_generic_profile_type==PROFILETYPE_8BIM) { decode_to_membuf = 1; } else if(tcc->im_generic_profile_type==PROFILETYPE_IPTC) { if(c->extract_level>=2) { dump_to_file = 1; ext = "iptc"; } else { decode_to_membuf = 1; } } else if(tcc->im_generic_profile_type==PROFILETYPE_ICC) { dump_to_file = 1; ext = "icc"; } else { if(c->extract_level>=2) { dump_to_file = 1; ext = "profile.bin"; } } if(dump_to_file) { dbuf *outf; outf = dbuf_create_output_file(c, ext?ext:"bin", NULL, DE_CREATEFLAG_IS_AUX); de_decode_base16(c, inf, pos, dlen, outf, 0); dbuf_close(outf); } if(decode_to_membuf) { dbuf *tmpf; tmpf = dbuf_create_membuf(c, 0, 0); de_decode_base16(c, inf, pos, dlen, tmpf, 0); if(tcc->im_generic_profile_type==PROFILETYPE_8BIM) { de_fmtutil_handle_photoshop_rsrc(c, tmpf, 0, tmpf->len, 0x0); } else if(tcc->im_generic_profile_type==PROFILETYPE_IPTC) { de_fmtutil_handle_iptc(c, tmpf, 0, tmpf->len, 0x0); } dbuf_close(tmpf); } done: ; }
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); }